C ++ STL内存管理:堆栈还是堆?

时间:2012-07-28 09:49:26

标签: c++ memory-management stl

通常当我使用非本地范围内的STL对象时,我会存储指向我想要存储的数据的指针。例如

std::vector<MyStruct*> 

当清理矢量时,我会通过并删除所有内容。我最近注意到这没有必要像我想的那样。无论出于何种原因,我认为STL类将数据存储在堆栈中,而我现在认为它在堆上分配它。它是否正确?将对象存储为减少复制时间的指针是唯一真正的好处吗?

4 个答案:

答案 0 :(得分:6)

标准容器通过Allocator对象分配内存,该对象的类型作为模板参数传递。如果你没有传递任何其他内容,那将是std::allocator<T>,它将使用new来分配内存。

底线:您可以强制他们以任何方式分配内存,但默认情况下它将来自免费商店。

如果你真的想要一个指针容器,容器将拥有指针对象,(例如,当对象被销毁时会自动删除它们),你可能想要看看Boost Pointer Containers

答案 1 :(得分:3)

使用指针减少复制时间 是一个真正的好处。想想所有可以改进的矢量操作 - 比如排序,例如。

另一个真正的好处(如上面的评论所述)是,这允许您使用多态并在同一向量中存储相关的对象。标量对象(非指针)无法做到的事情。

无论是将数据存储在堆栈还是堆上,都不会影响移动该对象的成本(嗯......确实如此,但通常可以忽略不计,在本次讨论中无关紧要)。

当您在STL向量中存储指向对象的指针时,向量不会取得对象的所有权。你仍然需要做尽职调查,并在不再需要它们时进行清理。

答案 2 :(得分:3)

  

[...]而我现在认为它在堆上分配它。这是对的吗?

是。如果将向量声明为:

std::vector<MyStruct*> v;

然后你基本上将指针存储在向量中,因此向量将分配内存来存储指针,而不是指针所指向的对象。因此,当析构函数运行时,向量将释放已分配的内存,它不会释放指针的内存,即它不会释放存储在向量中的指针所指向的内存。

但是,如果您声明:

std::vector<MyStruct> v;

然后你自己存储对象,因此向量将分配内存来存储对象,并在析构函数运行时释放它。

答案 3 :(得分:2)

  

当清理矢量时,我会经历并删除   一切。我最近注意到这不像我一样   以为是。

不要假设。如果向量中的指针指向动态分配的内存,那么 WILL 需要删除该内存,因为向量不会为您执行此操作。

例如,如果您的代码属于

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

 ...
 ...

 myVector.clear();

您有内存泄漏,因为您没有专门删除分配给添加到向量的每个元素的内存。向量释放它在自身内部分配的内存作为动态数组的一部分,但这只是释放了指针数组,而不是它们指向的内存