1
struct Test
{
    int var;
    char *arr;
}

int main()
{
    Test a;
    a.arr = new char[50];
}

The above code would create a dynamic array in the structure but the dynamic array would not be actually memory allocated within the structure, its memory would be allocated somewhere else. I want this array to be allocated in the structure as with the fixed array but I don't want to use fixed array. Any ideas? I've tried my best to clarify my question, hope you understand.

I want to send this structure through UDP and UDP takes continues memory buffer to send that's why I want this structure to have continuous memory.

Uzair Farooq
  • 917
  • 3
  • 15
  • 25
  • 2
    Could you explain why you need that? It would clarify your question a bit more. – Mat Nov 12 '11 at 14:14
  • Any particular reason for not using `std::vector` or `std::array`? – Tamás Szelei Nov 12 '11 at 14:15
  • 1
    possible duplicate of [How to declare a constant array in class with constant class variable?](http://stackoverflow.com/questions/8104777/how-to-declare-a-constant-array-in-class-with-constant-class-variable) --- Didn't you just ask this very question, only worded slightly differently? So because we told you that what you want (a static, yet variable type) doesn't exist in C++, you think that if you keep asking it'll eventually become possible? – Kerrek SB Nov 12 '11 at 14:20
  • 1
    I want to send this structure through UDP and UDP takes continues memory buffer to send that's why I want this structure to have continuous memory. – Uzair Farooq Nov 12 '11 at 14:22
  • @UzairFarooq: There's no reason why you can't use normal, dynamic allocation for that. Just allocate `sizeof(int) + N` bytes, fill the top with the integer and then send the whole thing. – Kerrek SB Nov 12 '11 at 15:05

7 Answers7

3

You can not do that as the new memory is from heap/ free store and your a will be allocated on stack....

you can allocate using malloc/new a continous memory block of sizeof Test + your required size and make the pointer arr to point at the end of the Test structure.

If you need it in function scope on stack you can use alloca.

Test *a = (Test*)alloca(sizeof(Test)+yoursize);
a->arr = (char*)a+sizeof(Test)...
joy
  • 1,569
  • 8
  • 11
1

No you cannot have variable length arrays in C++.
So you cannot do that.

You can have a fixed length array or you can use the approach you have given.

Another approach is,
You can use placement new to place your array at an pre-allocated memory location. This memory could be on stack.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

Your code don't compile. You should compile it with all warnings enabled, and improve it till you got no warnings. And are your studying C or C++? If it is C++, consider using std::vector

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0
struct Test {
  int var;
  char arr[1];
};

int main()
{
    std::vector<char> buf;
    buf.resize(sizeof(Test) + 50);
    Test *foo = reinterpret_cast<Test *>(&buf[0]);
    foo->arr[40] = 'b';
}
fghj
  • 8,898
  • 4
  • 28
  • 56
  • can u explain a little, what's going on – Uzair Farooq Nov 12 '11 at 14:28
  • @UzairFarooq this is a c++ solution, mine is a C solution. The difference is where the array will be stored, in my example is on stack, in this example it is in the free store/heap. – joy Nov 12 '11 at 14:33
  • As mentioned, this is old trick. Things that should be mentioned, that arr should be at least one length, some compilers not understand char arr[0]. When compiler see foo->arr[40], it just add offset to pointer "foo", so you can use array of any length, if foo point to suiltable location. You can allocate space for it anywhere, stack or heap. But you should remember about align restrictions. When you use reinterpret_cast, you say to compiler, I know what I do. So for some cpu compiler may expect that pointer to foo align to 4 or 8 bytes (if you allocate space on heap, this is should be so). – fghj Nov 12 '11 at 14:42
0

You can pass array size to structs constructor and allocate memory for array there. Don't forget to deallocate it somewhere, e.g. in destructor:

struct Test
{
    int m_var;
    char *arr;
public:
    Test(int var) : m_var(var)
    {
        arr = new char[m_var];
    }

    ~Test()
    {
        delete[] arr;
        arr = 0;
    }
};

void main(int argc, char* argv[])
{
   Test t(50);
   return 0;
}
Bojan Komazec
  • 9,216
  • 2
  • 41
  • 51
  • I think you misunderstood what OP wants. What he wants is to ensure that `&arr == &t + sizeof(int)` and not some random location. – Tamás Szelei Nov 12 '11 at 14:21
  • Yeah, I got it now when he added his last edit. He wants to consider entire struct in memory as buffer to send, so first sizeof(int) bytes are size and the rest (arr) is payload data... – Bojan Komazec Nov 12 '11 at 14:33
0

Although it hasn't been "blessed" like it has in C, most compilers will still let you use the "struct hack":

struct variable_array { 
    size_t size;
    char data[1];
};

The "trick" is that when you allocate it, you allocate enough space for the data you want to store (but this means it must be dynamically allocated):

variable_array *a = (variable_array *) ::operator new(sizeof(*a) + data_size);
a->size = data_size;

In theory, this isn't required to work -- the compiler could do a bound-check on references to the data member to ensure you don't index beyond the one element you've defined it to hold in the struct definition. In reality, I don't know of a single compiler that does such a thing, and kind of doubt that such a thing exists. Quite a lot of C code has done things like this for years, so a compiler that did such a check just wouldn't work with a lot of real-world code, even though the standard allows it. C99 also adds this (with minutely different syntax) as an official feature of the language.

Bottom line: it's a bit clumsy, but the possibility of really not working is almost entirely theoretical.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

Not truly dynamic allocation, but might solve your problem (depends on if you always know the desired size of the array at compile time)

template <size_t ArraySize>
struct Test
{
    int var;
    char arr[ArraySize];
}

int main()
{
    Test<50> a;      
}
Michael Price
  • 8,088
  • 1
  • 17
  • 24