Uzair Farooq
Uzair Farooq

Reputation: 927

dynamic array in structure with consecutive memory?

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.

Upvotes: 1

Views: 11640

Answers (7)

Michael Price
Michael Price

Reputation: 8968

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;      
}

Upvotes: 0

joy
joy

Reputation: 1569

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)...

Upvotes: 3

Jerry Coffin
Jerry Coffin

Reputation: 490108

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.

Upvotes: 0

Bojan Komazec
Bojan Komazec

Reputation: 9526

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;
}

Upvotes: 0

fghj
fghj

Reputation: 9394

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';
}

Upvotes: 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

Upvotes: 0

Alok Save
Alok Save

Reputation: 206518

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.

Upvotes: 1

Related Questions