Allocation/deallocation of variable length objects

Hi,

I have a (C++) project that involves structs of a dynamic size. It's ugly, but it's part of predefined interface and I have no choice but to use it.

For example:

struct someStruct{
int numItems;
someType Items[1];
};

The idea is to allocate (and free) this struct according to the number of items. The code I'm currently using is as follows:

int numItems = X;
someStruct * s = (someStruct*)operator new (sizeof(someStruct)+(numItems-1)*sizeof(someType));
delete someStruct;

my questions:

1) is this correct? will delete know how much memory to free?
2) is there another better/recommended way of doing this?

Thanks in advance!
I have a (C++) project that involves structs of a dynamic size.
Impossible. There's no such thing. The size of a structure or class has to be known at compile time. If a structure needs to hold a variable number of variables or objects it needs to use a pointer to a dynamic array or a vector.
Thank you so much for the feedback. However, this code is at least compiling successfully. Are you sure about what you said?
Almost right. As I understand it you want header, then an array of records. As you have it defined, your header has one element in it. It should be as follows.
1
2
3
4
struct someStruct{
    int numItems;
    someType Items[0];  // zero not one
};


The allocation is:
1
2
3
int numItems = X;
someStruct * s = (someStruct*)operator new(sizeof(someStruct) + (numItems)*sizeof(someType));
operator delete(someStruct);
Last edited on
Great! thanks for the information.

By the way, do I have to use "operator delete" ? or is just "delete" equivalent?

The only reason I used "operator new" was because it was the only syntax I could find that would allow me to put a specific size (like malloc does in C).
You have to use operator delete with allocations from operator new.
@nabeel:

You could do

 
(someStruct*)new char[ NUM_BYTES ];


You never need to explicitly use the keyword operator when calling new or delete.

BE WARNED, however, that the method you are using to allocate space for this
is not safe, in that there is no guarantee that new will return a pointer that
has the correct alignment for someStruct.

there is no guarantee that new will return a pointer that has the correct alignment for someStruct.


Really? Even if NUM_BYTES = sizeof(someStruct) / sizeof(char) ?
Yes. The returned buffer could be on any byte boundary.

Because in this case new it doesn't know the type it's allocating memory for. But it's no different from malloc in this regard.

In that case, do you have any recommendations to overcome this problem?

THanks again.
It may not be a problem. Intel x86 processors tend not to mind that sort of thing, and I've never had a problem with this in 3 decades of programming.

The constraint is usually imposed by the processor.
Now that I think about it, someType has to be a POD-type. It can't be a struct/class with
a constructor or destructor, a struct/class with any virtual functions, or a struct/class that
is a descendant of a derived type. In short, in reality it can only be a POD type.

If you can assume then that someType has the same alignment requirements as int, then
you could figure out how many bytes the array of someTypes needs, and then allocate
an array of ints:

 
ptr = (someStruct*)new int[ 1 + numItems / 4 + ( numItems % 4 ? 1 : 0 ) ];


wow, that's ugly.

1 + -> because you need space for numItems.
numItems % 4 ? 1 : 0 -> because if it requires 13 bytes, 13 / 4 = 3 * 4 = 12 bytes
allocated, too few, so you need to allocate 1 additional int to make it big enough.

Topic archived. No new replies allowed.