0

I need to make the size of the array defined inside the class as situation dependent value. To clarify the point , the following code having fixed array size shows no error

class CMinimalServer : public GBDataAccess
{
public:
    DWORD IdG[30];
    VARIANT Value[30];
    WORD Quality[30];
    FILETIME Timestamp[30], ft;
    HRESULT Error[30];

But I need to make the size of the array which is '30' in the above case as an dependable value. By this I mean to say that suppose in other part of the code, I have

if (a==b)
     Number = 10;
else
     Number = 30;

The size of the array should be 10 and 30 accordingly.

But the following code shows an error

class CMinimalServer : public GBDataAccess
{
public:
    DWORD IdG[Number ];
    VARIANT Value[Number ];
    WORD Quality[Number ];
    FILETIME Timestamp[Number ], ft;
    HRESULT Error[Number ];

I tried

#define Number 16

at the top and the above code showed no error but the problem is i cannot the modify the variable in other part of the code

//// Some issue in the solution

I have modified the code as per the suggestion: I have to make functions inside the class (createTag) .

// Class definition 
class CMinimalServer : public GBDataAccess
{
public:
struct Entry
{
    DWORD IdG;
    VARIANT Value;
    WORD Quality;
    FILETIME Timestamp;
    HRESULT Error;

};

 private:
    FILETIME ft;

 void createTag()
 {
    DWORD ids[NumberOfPoints],i;
    VARIANT val;
    val.vt = VT_BOOL;

    unsigned c=0;

    for (i = 0; i<NumberOfPoints; i++)
    {
        wchar_t opcid[NumberOfPoints];
        wsprintfW(opcid, L"Item%02i", i+1); 
        val.boolVal = VARIANT_FALSE; 
        srv.GBCreateItem(&ids[i], i, opcid, OPC_READABLE|OPC_WRITEABLE, 0, &val);
        Entry.IdG[c] = ids[i]; 
        Value[c].vt= VT_BOOL; 
        c++;
    }
.....
}

//Main function
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int   nShowCmd)
{
    CMinimalServer() = default;
CMinimalServer(int number) : tab_(number){};
std::vector<Entry> tab_ = std::vector<Entry>(30);
}

The issues are:

  1. How to define idG vector array inside the CreateTag function.

Entry.idG[c] is showing error.

  1. The 'NumberOfPoints' in the loop of createTag function is also equal to 30. how to assign this value in the main function.
  2. How to make another vector array ids . can i defined it in the same struct entry and call it in createTag.
1
  • 2
    Why not use std::vector ? Commented Feb 5, 2014 at 9:57

5 Answers 5

9

We have vector in C++

#include <vector>
class CMinimalServer : public GBDataAccess {
public:
    struct Entry {
        DWORD IdG;
        VARIANT Value;
        WORD Quality;
        FILETIME Timestamp;
        HRESULT Error;
    };  

    CMinimalServer() = default;
    CMinimalServer( int number ) : tab_(number) {};

private:
    FILETIME ft;
    std::vector<Entry> tab_ = std::vector<Entry>(30);
};

You can of course use a vector for each separate value if you need them contiguous and access the underlying pointer with variable.data()

Sign up to request clarification or add additional context in comments.

8 Comments

Yes, it was already along the vector in CMinimalServer, not yet awake fully ^^
Shouldn't your Entry struct provide the vectors per member, to replicate the OP's sample? Or being omitted at all, and have the arrays replaced with std::vector<>.
The comment about contiguous array and data is for that purpose. Having split arrays need more work to keep size in sync and should be preferred only if there is a reason ( memory cache performance, legacy API ).
this allows size modification which was not stated as a desired feature in the question
@bobah "I need to make the size of the array defined inside the class as situation dependent value." first line of OP?? I think you're wrong.
|
1

If number is to be defined in runtime then the solution to this is to define your class as:

    class CMinimalServer : public GBDataAccess
    {
    public:
        DWORD* IdG;
        VARIANT* Value;
        WORD* Quality;
        FILETIME* Timestamp;
        FILETIME ft;
        HRESULT* Error;

        CMinimalServer(int number)
        {
             IdG = new DWORD[number];
             Value = new VARIANT[number];
          ... etc
        }

        ~CMinimalServer()
        {
             delete[] IdG;
             delete[] Value;
           ... etc
        }
   }

2 Comments

You should not show naked pointer as this is a bad habit, at least, use a smart pointer like unique_ptr.
@galop1n Smart pointers aren't a panacea; in this case, he should use std::vector, rather than pointers. But if he's going to use pointers: in this case, they must be smart pointers. The code as written leaks memory (and is thus incorrect).
0

The ISO doesn't allow a variable-length array. However, there is a loophole. You can create the array with a variable as its size at runtime using dynamic memory.

For example: int x =4; int *a = new int[x];

Don't forget to use delete!

delete[] a;

I hope that helps!

Comments

0

If you want a non compiletime const size array, use std:vector.

3 Comments

While being technically correct, this is the worst answer among all the others here!
@πάνταῥεῖ Actually, it's the only one which is correct.
@JamesKanze After looking through all of them again, I must omit you're right. Downote retracted ...
-2

Edited : from naked pointers to shared pointers,

Dynamic memory allocation with pointers will do it,

class CMinimalServer : public GBDataAccess
{
public:
 shared_ptr<DWORD> IdG;
 shared_ptr<VARIANT> Value;
 shared_ptr<WORD> Quality;
 shared_ptr<FILETIME> Timestamp, ft;
 shared_ptr<HRESULT>* Error;

Then inside the constructor assign them the memory (define array size), like this

CMinimalServer::CMinimalServer()
{
  IdG = new DWORD(Number);
  Value = new VARIANT(Number);
  Quality = new WORD(Number);
  Timestamp = new FILETIME(Number);
}

5 Comments

You should not show naked pointer as this is a bad habit, at least, use a smart pointer like unique_ptr.
new DWORD(Number) This is plain wrong, if you want to allocate an array use new DWORD[Number]... And there is no point in using arrays in this context when it is possible to use a std::vector, especially since there is a need to dynamically expand the arrays.
okay, let me replace this with shared_ptr, latest c++11, yeah STL containers are better options, i agree
This is Undefined Behaviour. You can't just use shared_ptr for arrays (it seems to be possible, but rather complicated).
As it stands your answer is plain wrong shared_ptr<DWORD>,new DWORD(Number) in no way serve as an array as requested by the OP!.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.