当我完成向量时,我需要调用 clear() 吗?

Do I need to call clear() when I am done with a vector?

本文关键字:clear 调用 向量      更新时间:2023-10-16

我看到的所有问题都问到当向量的元素被动态分配/是指针时管理内存。我的问题只是关于已在堆栈上分配的向量,具有简单的类型,例如int.

如果我有以下代码:

std::vector<int> vec(5);
for(int i = 0; i < vec.size(); i++) {
std::cout << vec[i] << std::endl;
}

完成后我需要打电话clear()吗?

No.

C++中的类有一个析构函数,当类对象超出范围或删除时,将调用该析构函数。虽然您是正确的,std::vector动态分配后台空间,但std::vector析构函数将为您释放内存,从而产生一个快乐的无泄漏程序。

从 cppreference 页面,当向量析构函数被调用时...

破坏容器。调用元素的析构函数,并解除分配使用的存储。请注意,如果元素是指针,则不会销毁指向的对象。


另请注意,从 cpp 首选项上清除,函数...

保持向量的容量()不变...

因此,当您调用clear时,内存甚至实际上都没有释放!(有关clear实际在做什么的更多信息,请参阅此SO问题)

如果您担心释放(大)vector中分配的内存(因此被阻止在其他地方使用),您应该

  1. 确保相应矢量的范围/生存期限制为其即将使用的区域/时间,以便销毁矢量自动释放内存。

  2. 如果做不到这一点(无论出于何种原因),您可以

    vec.clear();          // reduces the size to 0, but not the capacity
    vec.shrink_to_fit();  // suggests to reduce the capacity to size
    assert(vec.capacity()==0);
    

请注意,vector::clear()不会取消分配vector内存(仅由矢量元素动态分配的内存(如果有)。vector::shrink_to_fit()建议将vector的内存占用量减少到其实际大小,但实现可以选择忽略该请求。

最后,clear()后跟shrink_to_fit()的替代方法是交换习惯用语(在 C++11 之前也有效):

vector<Tp>().swap(vec);
assert(vec.capacity()==0);

这里发生的事情是构造一个新的空向量(相同类型),然后立即与vec交换,这样vec就变成了空(大小和容量为零)。最后,由于新向量是一个临时(未命名)对象,因此它被破坏,从而取消分配最初与vec一起保存的内存。