Search code examples
c++arraysvectordynamic-memory-allocationheap-memory

Is it safe to "dissolve" c++ arrays on the heap?


I am currently implementing my own vector container and I encountered a pretty interesting Issue(At leas for me). It may be a stupid question but idk.

My vector uses an heap array of pointers to heap allocated objects of unknown type (T**). I did this because I wanted the pointers and references to individual elements to stay same, even after resizing.

This comes at performance cost when constructing and copying, because I need to create the array on the heap and each object of the array on the heap too. (Heap allocation is slower than on the stack, right?)

T** arr = new *T[size]{nullptr};

and then for each element

arr[i] = new T{data};

Now I wonder if it would be safe, beneficial(faster) and possible, if instead of allocating each object individually, I could create a second array on the heap and save the pointer of each object in the first one.Then use (and delete) these objects later as if they were allocated separately.

=> Is allocating arrays on the heap faster than allocating each object individually?

=> Is it safe to allocate objects in an array and forgetting about the array later? (sounds pretty dumb i think)

Thanks for your help :)


Solution

  • First a remark, you should not think of the comparison heap/stack in terms of efficiency, but on object lifetime:

    • automatic arrays (what you call on stack) end their life at the end of the block where they are defined
    • dynamic arrays (whay you call on heap) exists until they are explicitly deleted

    Now it is always more efficient to allocate a bunch of objects in an array than to allocate them separately. You save a number of internal calls and various data structure to maintain the heap. Simply you can only deallocate the array and not the individual objects.

    Finally, except for trivially copyable objects, only the compiler and not the programmer knows about the exact allocation detail. For example (and for common implementations) an automatic string (so on stack) contains a pointer to a dynamic char array (so on heap)...

    Said differently, unless you plan to only use you container for POD or trivially copyable objects, do not expect to handle all the allocation and deallocation yourself: non trivial objects have internal allocations.