解除std :: vector对象的"正确"方法

Jac*_*cob 34 c++ memory-management stl vector

第一个解决方案是:

std::vector<int> *vec = new std::vector<int>;
assert(vec != NULL);
// ...
delete vec;
Run Code Online (Sandbox Code Playgroud)

另一种选择是:

std::vector<int> v;
//...
vec.clear();
vec.swap(std::vector<int>(vec));
Run Code Online (Sandbox Code Playgroud)

第二种解决方案有点诀窍 - 这种"正确"方式是什么?

更新:

我知道析构函数一旦离开堆栈就会被调用,我很好奇其他方法.

Jar*_*Par 37

解除分配矢量的最简单和最可靠的方法是在堆栈上声明它并且什么都不做.

void Foo() {
  std::vector<int> v;
  ...
}
Run Code Online (Sandbox Code Playgroud)

C++保证v在方法执行时将调用析构函数.析构函数std::vector将确保释放它分配的任何内存.只要T类型vector<T>具有适当的C++解除分配语义所有都会顺利.

  • 您不一定需要将使用向量的代码移动到另一个函数.如果你将它与`{...}`一起使用的代码块包围,那么析构函数将在该块的末尾被调用. (12认同)
  • @Jacob:那你为什么还要做其他事呢?尝试做任何事情来解除分配矢量都没有必要,也没有意义. (5认同)

Mik*_*our 15

在不破坏矢量对象本身的情况下,释放向量中所有存储的最简单方法是

vec = std::vector<int>();
Run Code Online (Sandbox Code Playgroud)

你的第二个变体将具有相同的效果,但它会在途中跳过更多的箍."复制和交换"技巧会释放向量中的任何额外容量,如果它包含您想要保留的某些数据,则会很有用.如果没有数据,则无需复制或交换.

  • 是的,它是不同的,因为调整大小和清除都执行相同的操作 - 它们清除向量的内容(调用成员析构函数等),但不会释放向量已保留的内存。即您正在更改向量的 size(),但不更改容量()。创建一个新向量并将其分配给旧向量确实会释放原始向量的内存。 (3认同)
  • ...或更清晰的“vec.clear()”?(没有双关语的意思) (2认同)

def*_*ode 13

std::vector<int> vi;
/*push lots of stuff into the vector*/

// clean it up in C++03
// no need to clear() first
std::vector<int>().swap(vi);

// clean it up in C++0x
// not a one liner, but much more idiomatic
vi.clear();
vi.shrink_to_fit();
Run Code Online (Sandbox Code Playgroud)

  • 如果向量具有不同的分配器,则`swap`技巧不起作用!我刚刚发现这很难.可能是非常罕见的事情,所以我不知道它是否值得提及比这个评论更突出. (7认同)
  • `shrink_to_fit`只是一个暗示,实际收缩并不能保证. (4认同)
  • 'shrink_to_fit`的原因是提示它允许带内存的花哨东西.如果向量使用小字符串优化(不太可能),或者如果向量总是从池中分配并且最小大小大于当前向量大小,则缩小到适合将意味着更少.然而,可以假设`shrink_to_fit()`将使向量尽可能小. (3认同)