我知道如果我在堆栈上创建了一个向量,如下所示:
void foo(){
std::vector<int> vec;
}
执行完成后foo
,分配给 vec 的内存被释放。但是,我如何在foo
. 我不是在寻找 vec.clear() 因为它只是清除容器,它确实释放了分配给容器的内存。
使用{}
范围块来更密切地控制向量的生命周期:
void foo()
{
{
std::vector<int> vec;
// stuff that uses vec
}
// stuff that doesn't
}
您可以shrink_to_fit
在 C++11 中使用,并在C++03 中尝试与技巧相关的等效项,但为什么呢?!
你需要什么都不做。它将自行处理,因为向量类中的析构函数会破坏向量,并在函数结束时变量超出范围时释放内存。
编辑:如果你真正想要做的是像阅读大量数字,然后删除所有不能被 6、7、2 整除但不等于 42 的数字,那么我会说它是最好创建第二个向量来存储您不想保留的数字,然后让原始向量超出范围。
如果vec.resize(0); vec.shrink_to_fit();
上面建议的 (C++11) 不可用,您可以获得与vector<int>().swap(vec);
. 尽管最好将其放入额外的{}
块中,但如果可以这样做(并不总是容易,但通常是可行的)。
但是请注意,与临时对象进行交换很可能会对您交换的临时对象进行(不必要的)动态分配,并在当前范围结束之前分配一个小块。
它显然也不会释放实际 vector
对象(与其持有的数据相反)在堆栈上占用的 4-8 字节内存(只有作用域的末尾可以这样做)。
也就是说,在大多数情况下,整个努力都是徒劳的。如果您稍后在同一范围内不需要大量内存,那么早或晚释放向量并不重要。要么它已经很早就失败了(在这种情况下,整个问题都不会出现!),要么它会以任何一种方式工作到函数的末尾。
另一方面,如果您知道稍后在同一个函数中需要大量内存(例如,另一个类似大小的向量)并且可以合理地预期这将成为一个问题,那么很难预测是否释放第一个真的很重要(想想碎片化,尤其是在做这个swap
把戏的时候)。
如果第二个向量与第一个向量大小相同或更小,您只能期望它能够可靠地工作,在其他所有情况下,它不能保证更好地工作。
在我看来,您可以通过以下方式释放向量中分配的全部内存:
1. 使用方法 clear() 调整向量的大小,然后使用 shrink_to_fit() 确保向量中的所有元素都被实际释放。
2. 如果您的向量包含指针元素,请使用智能指针 (shared_ptr, unique_ptr) 而不是原始指针(在 ANSI C 中)。
3. 如果您使用原始指针,请不要忘记在停止使用它们时释放()它们。