C ++ vector :: clear

时间:2010-08-13 14:19:32

标签: c++ vector

vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

    vector<weight> (decoy).swap(decoy);  
}

在上述方法clear_decoy()中,vector<weight> (decoy).swap(decoy); 意味着什么?

方法是否清除decoy?谢谢!

6 个答案:

答案 0 :(得分:22)

我以前从未见过这种形式。

我看到它写成:

vector<weight>().swap(decoy);

这意味着“创建一个新的空向量,并将其与现有向量交换。

vector<weight> (decoy).swap(decoy);

要理解这一点,请突破部分。

vector<weight>(decoy)创建一个新的向量(从现在空的诱饵中复制它的内容)。新的向量是一个自治的临时值,所以我们要说它的名字是newvector

newVector.swap(decoy);使用decopy交换新矢量。

(根据评论更新以修复错误)

答案 1 :(得分:20)

它会创建一个Weight个对象的新向量(它将为空)并将其与decoy交换。

原因是默认情况下,std::vector<t>::clear通常不会减少向量使用的存储空间,它只会破坏其中包含的所有对象。通过这种方式,向量可以存储更多对象而无需在将来重新分配。

但是,有时您想要修剪向量中的容量。使用新创建的向量进行交换(直到它的行结束,因此在那里被销毁)释放向量分配的所有内存。

答案 2 :(得分:10)

该代码尝试使用公共技巧以确保释放向量分配的内存失败。实际上可能会或可能不会这样做,具体取决于向量的复制构造函数是否分配内存以匹配其他向量的大小或其容量。

要可靠地释放内存,请使用以下命令:

void clear_decoy() {  
    vector<weight>().swap(decoy);  
}

这会创建一个临时空向量(分配很少或没有内存),将其与decoy交换,以便内存现在由临时所有,然后销毁临时内容,释放内存。

答案 3 :(得分:6)

clear从向量中删除所有条目,但可能不一定要释放空间。这个交换习惯用法将向量恢复为没有分配空间。

答案 4 :(得分:3)

正如0A0D所提到的,swap的作用是在两个向量之间交换潜在的受控记忆。但这需要更多解释。

当你clear vector时,至少就程序员而言,元素会被删除。 size()变为零,capacity()可能会也可能不会发生变化。但是标准并不保证向量使用的内存实际上会返回给操作系统。因此,如果在clear()之前的向量中有1000个元素,并且每个元素占用1000个字节的内存,则在调用每个元素的析构函数clear()之后,但向量可能仍然保持1,000,000字节的分配。

这有时是不受欢迎的。您在上面说明的'交换技巧'具有在两个向量之间交换受控存储器的效果。因此decoy最终会受到内存重置的控制。

以下是一步一步发生的事情:

  1. decoy元素均为erased。 元素的析构函数是 调用,矢量size() 变为零。实际的记忆可能 不能解除分配。
  2. 在堆栈(vector<weight> (decoy))上构建一个新向量,并将decoy中的元素复制到其中。由于decoy仅为clear(),因此不会将任何元素复制到临时向量中。但是,请参阅下面的编辑。您不知道未交换受控内存。
  3. 临时向量和decoy的内存交换(.swap(decoy);),导致decoy被清除,内存被转移到临时值。
  4. 临时从堆栈中掉落,导致内存被释放。
  5. 这被称为“the swap trick”。

    编辑:正如迈克提到的那样,原来的程序员做错了。临时不应该基于decoy构建,它应该是默认构造的。您不确定swap()只会复制元素,而不会复制下面的受控内存。

答案 5 :(得分:1)

清楚,

  

矢量的所有元素都是   丢弃:他们的析构函数被称为   然后将它们从中删除   矢量容器,离开了   容器大小为0。

交换只是交换两个向量,

  

交换内容

     

通过传递矢量的内容   vec的内容,这是另一个   相同类型的矢量。尺寸可以   不同。

     

致电此会员后   功能,这个元素   容器是那些在vec中的容器   在通话之前,和   vec就是那些。所有   迭代器,引用和指针   对于交换的向量仍然有效。

看起来你真的没有交换任何东西,只是恢复到默认分配。清除可以解除分配,但有时不会。您不仅要缩小大小,还要减少使用swap语句分配的空间。