【问题标题】:Range Based For Loop基于范围的 For 循环
【发布时间】:2016-10-31 15:04:34
【问题描述】:

我的问题是:当我在这个例子中使用基于范围的 for 循环时,它是否会释放存储在 'vec' 中的每个 'Object' 堆上的内存?我有一个想法,这只是复制一个指针,然后试图释放复制的指针。

我相信 'auto *& obj : vec' 是在声明 'obj' 对指针的引用,然后将存储在 'vec' 中的每个对象的地址分配给它,它的内存将被释放,并设置为空指针。是这样吗?

std::vector <Object*> vec;
vec.push_back(new Object{});
vec.push_back(new Object{});
//....

//clean up
for(auto *& obj : vec)
    delete obj, obj = nullptr;

【问题讨论】:

  • 这不是你清理矢量的方式。它有自己的机制。你真的需要一个指针向量吗?使用 RAII
  • 如果你使用对象而不是指针,一旦向量超出范围,它们将被自动清理,或者你调用向量的清空函数
  • 您的代码对我来说看起来不错。从文体的角度来看,我宁愿使用{ delete obj; obj = nullptr; }
  • 如果你有基于范围的 for,你有 std::unique_ptr 并且应该考虑使用它。
  • 如果您想存储类型层次结构中的多种类型,则需要指针。

标签: c++ for-loop heap-memory


【解决方案1】:
std::for_each(vec.begin(), vec.end(), [](Object* pt){delete pt; pt = nullptr;});

这应该可行。

【讨论】:

  • pt = nullptr; 部分没有任何用处。
  • 它不会自动设置为 nullptr (据我所知,它不是 C++ 标准的一部分),并且有一个指向内存的非空指针向量从来都不是一个好主意。清除并免费被其他代码重用。
  • 全部为真,但您将函数局部变量设置为nullptrvec 仍包含deleted 指针。
  • 好点:),我错过了。那么是对指针的引用吗?
  • 除了不回答问题并包含错误(如 R Sahu 指出的那样)。老实说:你真的认为这比 OP 的解决方案更好吗?
【解决方案2】:

当我在本例中使用基于范围的 for 循环时,它是否会释放存储在 'vec' 中的每个 'Object' 的堆上的内存?

是的。

我以为这只是复制一个指针,然后试图释放复制的指针。

它不复制指针。但是,删除指针的副本与删除指针的作用相同,因此这对指向的对象是否被销毁没有影响。删除后的赋值中是否将原始指针设置为null,确实有区别。

我相信 'auto *& obj : vec' 是在声明 'obj' 对指针的引用,然后将存储在 'vec' 中的每个对象的地址分配给它,它的内存将被释放,并设置为空指针。是这样吗?

这基本上是对的。虽然,如果我们是迂腐的,该代码会将存储在vec 中的每个对象分配给引用。这是因为vec中存储的对象是Object实例的地址。

您需要澄清代码的作用意味着它不是很好。在这种情况下,您可能会受益于不使用auto

for(Object*& obj : vec) {
    delete obj;
    obj = nullptr;
}

另外,考虑存储空指针向量是否有意义。我建议您不要将指针设置为 null,而只需完全删除指针:

for(Object* obj : vec)
    delete obj;
vec.clear();

更清晰,不是吗?

【讨论】:

  • 是的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2014-12-06
  • 2014-01-12
  • 2013-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-25
相关资源
最近更新 更多