简体   繁体   中英

C++ STL Memory Management: Stack or Heap?

Normally when I use STL objects that are in a non-local scope I store pointers to the data I want to store. For instance

std::vector<MyStruct*> 

When it's time to cleanup the vector I then go through and delete everything. I've recently noticed that this isn't necessary like I thought it was. For whatever reason I was thinking the STL classes stored data on the stack, whereas I now think it allocates it on the heap. Is this correct? Is the only real benefit to storing objects as pointers to reduce copy time?

The standard containers allocate memory via an Allocator object, whose type is passed as a template parameter. If you're not passing anything else, that'll be std::allocator<T> , which will use new to allocate the memory.

Bottom line: you can force them to allocate memory almost any way you want to, but by default it'll come from the free store.

If you really want a container of pointers were the container will own the pointee objects, (eg, will automatically delete them when the object is destroyed), you might want to look at Boost Pointer Containers .

Using pointers to reduce copy time is a real benefit. Think of all the vector manipulations that can be improved by that - like a sorting, for example.

Another real benefit (as noted in a comment above) is that this allows you to use polymorphism and store related objects in the same vector. Something you cannot do with scalar objects (non-pointers).

Whether you store data on stack or heap doesn't make a difference to how expensive it is to move that object (well... it does, but often quite negligible and not relevant in this discussion).

When you store pointers to your objects in an STL vector the vector does not take ownership of your objects. You still need to do due diligence and clean them up when they are not needed anymore.

[...] whereas I now think it allocates it on the heap. Is this correct?

Yes. If you declare the vector as:

std::vector<MyStruct*> v;

then you're basically storing pointers in the vector, so the vector will allocate memory to store the pointers , not the objects pointed to by the pointers. So when the destructor runs, the vector will deallocate memory which it has allocated, it will not deallocate memory of the pointers themseves, ie it will not deallocate the memory pointed to by the pointers stored in the vector.

However, if you declare this:

std::vector<MyStruct> v;

then you're storing objects themselves, so the vector will allocate memory to store the objects, and it will deallocate it when the destructor runs.

When it's time to cleanup the vector I then go through and delete everything. I've recently noticed that this isn't necessary like I thought it was.

Don't assume that. If the pointers in your vector point to dynamically allocated memory then you WILL need to delete that memory, as the vector will not do it for you.

For example if your code is of the type

 MyStruct* pNewStruct = new MyStruct;
 myVector.push_back(pNewStruct);

 ...
 ...

 myVector.clear();

you have a memory leak as you have not specifically deleted the memory you allocate to each element you add to the vector. The vector frees the memory it allocates within itself as part of being a dynamic array, but this just frees the array of pointers, NOT the memory that they point to

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM