【问题标题】:C++ vector::clearC++ 向量::clear
【发布时间】:2010-08-13 14:19:32
【问题描述】:
vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

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

上面的方法clear_decoy(),请问vector&lt;weight&gt; (decoy).swap(decoy); 是什么意思?

该方法是否清除decoy?谢谢!

【问题讨论】:

  • 记得点击他们的复选标记来接受您认为最好的答案

标签: c++ vector


【解决方案1】:

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

我看过它写成:

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

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

vector&lt;weight&gt; (decoy).swap(decoy);

要理解这一点,请分解。

vector&lt;weight&gt;(decoy) 创建一个新向量(其内容从现在为空的诱饵复制而来)。新向量是一个临时的匿名向量,所以我们假装它的名字是newvector

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

(根据 cmets 更新以修复错误)

【讨论】:

  • +1 表示同一事物的更好(和更多)通用结构。
  • 必须是vector&lt;weight&gt;().swap(decoy)。您可以在临时对象上调用成员函数,但不能将它们作为非常量引用参数传递。
  • 我觉得C++0x STL定义中增加了shrink的方法,根据实际大小减少内存占用……还是这是一厢情愿?
  • @Matthieu:是的,它被称为shrink_to_fit,但实现不必尊重它。
  • 好吧,即使是空向量,实现也不必将容量减少到 0。他们甚至可以将小字符串优化应用于向量类,我只是觉得值得一提:)
【解决方案2】:

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

原因是默认情况下,std::vector&lt;t&gt;::clear 通常不会真正减少向量使用的存储空间,它只会破坏其中包含的所有对象。这样,向量就有空间存储更多对象,而无需在未来重新分配。

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

【讨论】:

  • 天哪!我亲爱的 C++,你比我们聪明,给爱你的人带来麻烦。
  • 聪明是有社会成本的。
  • 这是非常 C++ 的。 C++ 在这里公开了内存管理,因此您有机会根据需要自定义内容。默认情况下,C++ 会尽可能快,因此如果您不遵循此代码,您将获得更快的代码。如果你有一个非常大的向量并且你删除了它的许多元素,那么你可以使用这个习惯用法来为操作系统释放资源,但会牺牲速度。通常您不想这样做(即,不要修复未损坏的部分)。
【解决方案3】:

该代码尝试使用常见技巧确保释放向量分配的内存失败。它实际上可能会也可能不会这样做,这取决于向量的复制构造函数是否分配内存以匹配另一个向量的大小或容量。

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

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

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

【讨论】:

  • 虽然这是真的,但这里没有合理的 STL 实现会根据容量进行分配。
  • @Billy:确实;笨拙的 clear-copy-swap 舞蹈很可能会奏效,但更简单的版本保证会奏效。
【解决方案4】:

clear 从向量中删除所有条目,但不一定会释放空间。此交换习语将向量恢复为未分配空间。

【讨论】:

  • 其实clear可以释放vector占用的空间。但它没有必须。但它通常不会出现在大多数 STL 实现中。
【解决方案5】:

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

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

这有时是不可取的。您在上面提到的“交换技巧”具有在两个向量之间交换受控内存的效果。因此decoy 以受控内存重置结束。

这是一步一步发生的事情:

  1. decoy 元素每个都是 erased。 元素的析构函数是 调用,向量的size() 变为零。实际内存可能 不会被释放。
  2. 在堆栈上构造一个新向量 (vector&lt;weight&gt; (decoy)),并将 decoy 中的元素复制到其中。因为decoy 只是clear()ed,所以没有元素被复制到临时向量中。但是,请参阅下面的编辑。你不知道受控内存没有交换。
  3. 临时向量和 decoy 的内存被交换 (.swap(decoy);),导致 decoy 都被清除,并将其内存转移到临时向量。
  4. 临时从堆栈中掉下来,导致它的内存被释放。

这被称为“the swap trick”。

编辑:正如迈克所说,最初的程序员做错了。临时不应该基于decoy 构建,它应该只是默认构建。你不确定swap() 只会复制元素而不是下面的受控内存。

【讨论】:

    【解决方案6】:

    清晰,

    向量的所有元素都是 丢弃:它们的析构函数被调用, 然后将它们从 矢量容器,离开 大小为 0 的容器。

    Swap 只是交换两个向量,

    交换内容

    通过以下方式交换向量的内容 vec 的内容,这是另一个 相同类型的向量。尺寸可能 不同。

    调用此成员后 函数,this中的元素 容器是那些在 vec 在调用之前,以及 vec 是其中的那些。全部 迭代器、引用和指针 对交换的向量仍然有效。

    您似乎并没有真正交换任何内容,只是恢复到默认分配。 Clear 可以解除分配,但有时不能。您不仅减少了大小,而且减少了交换语句分配的空间。

    【讨论】:

    • @ladyfafa:使用 swap 语句,分配的空间量减少了。这就是向量的优点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多