【问题标题】:Move a dynamically allocated variable into a vector将动态分配的变量移动到向量中
【发布时间】:2017-03-10 17:05:57
【问题描述】:

给出以下 C++ 代码:

std::vector<int> myVec;
int* num = new int(1);
myVec.emplace_back(std::move(*num));

如果将具有动态存储持续时间的变量移动到容器中(例如向量),如果 myVec 被销毁(超出范围),是否仍然需要手动删除 num?如果我使用push_back 而不是emplace_back,有什么区别吗?

【问题讨论】:

  • 您不是在“移动变量”。您正在添加一个向量元素,其值与堆上对象的值相同。
  • 如果你使用 std::string 这样的移动构造函数和复制构造函数实际上不同的东西,动机可能会更清楚

标签: c++ vector heap-memory move


【解决方案1】:

您正在将*num 中存储的值复制到向量中。
和这样做没有太大区别:

int* num = new int(1);
int cpy = *num;

因此,是的,您必须将其删除。
在代码中以某种方式处理指针时,向量不会神奇地处理对象的生命周期。


如果您想控制对象的生命周期,可以使用unique_ptrs:

myVec.emplace_back(std::make_unique<int>(1));

无论如何,这需要您将向量的类型从std::vector&lt;int&gt; 更改为std::vector&lt;std::unique_ptr&lt;int&gt;&gt;

否则,您可以这样做:

std::vector<int> myVec;
auto num = std::make_unique<int>(1);
myVec.emplace_back(*num);

一旦num 超出其范围,分配的内存将被释放。

【讨论】:

  • “向量不会神奇地处理包含对象的生命周期。” ——但他们确实如此。只是不是元素所复制的对象的生命周期。
【解决方案2】:

在您的情况下,不会发生 移动,因为您使用的是 原始类型 int,它将被简单地复制。

但是即使你移动堆上一个对象的到一个向量你仍然需要释放内存,因为moving 值仍然使 moved from 对象处于有效状态。它仍然存在并且可以使用。 移动的效果是它的值可能已经改变,因此在你重新分配一个新的值之前不能依赖它的值。

无论您使用emplace_back() 还是push_back()移动它仍然作为堆上的有效对象的值,所以我仍然需要独立地删除 vectormoved to 元素所发生的事情。

所以std::move() 促进(但不保证)移动对象的内容(或值) - 而不是对象本身,所以 移动自 对象仍然需要删除

【讨论】:

    猜你喜欢
    • 2020-06-15
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 2012-11-08
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多