【问题标题】:Clearing a vector of raw pointers to objects owned by unique pointers清除指向唯一指针拥有的对象的原始指针向量
【发布时间】:2018-06-03 11:48:01
【问题描述】:

我想知道最好的方法是清除vector 中的vectors 的原始指针,这些指针指向unique_ptrs 拥有的对象,而不会出现任何内存泄漏。

为了更具体,假设我有:

std::vector<std::unique_ptr<Person>> people;
std::vector<std::unique_ptr<Animal>> animals;
std::vector<std::vector<Animal*>> animalOwnerships;

我知道我可以使用people.clear()animals.clear(),这将删除指向类对象的唯一指针,这反过来又会删除类对象本身(如果我在这里弄错了,请纠正我)。

如果我先调用它们,那么animalOwnerships 是否包含悬空指针?是否可以此时调用 animalOwnerships.clear() 而无需担心任何内存泄漏,还是应该在其他两个之前先调用它?

另外,animalOwnerships中的个人vectors是否需要单独清除?

【问题讨论】:

  • 我不完全确定你在问什么。如果您不确定animalOwnershipsanimals 中的哪一个将首先被销毁,也许您需要与shared_ptr 共享所有权?如果它们(几乎)同时被清除,那么清除它们的顺序并不重要。 clear 一个悬空指针向量很好。有些人可能会欣赏先清除animalOwnerships 的整洁。
  • @FrançoisAndrieux 通常,animals 是永久性的。只有一个场景我会“重置”这些vectors,并且我可以完全控制我这样做的顺序。鉴于此,我应该在animals.clear() 之前调用animalOwnerships.clear() 吗?如果我连续清除它们真的很重要吗?如果我先打电话给animals.clear(),我会对正在发生的事情(在指针和内存方面)更好奇。
  • 当您清除 animals 时,您将销毁其中包含的每个 unique_ptr。这反过来又指向delete 每个指向Animal 的实例。此时,animalOwnerships 没有改变,但它的指针都是无效的(悬空)。您仍然可以销毁这些指针(不要与将它们交给delete 混淆)所以clear animalOwnerships 不是问题。
  • @FrançoisAndrieux 谢谢你的解释。另外,为了确保我理解,可以先clearanimalOwnerships,因为animalOwnerships 中的原始指针指向的Animal 对象/实例归unique_ptrs 所有。相反,如果这些对象没有no unique_ptrs,然后我调用了animalOwnerships.clear(),那么我就会发生内存泄漏,因为我会删除指向这些对象的唯一指针在记忆中。但是,感谢unique_ptrs,我不必再担心这个了。对吗?
  • 对。如果您只有原始指针,则在清除最后一个向量之前,您需要自己 delete Animal 实例。

标签: c++ c++11 pointers vector smart-pointers


【解决方案1】:

指针就像一张纸,上面列出了位置。

悬空指针是指向不存在的房子的地址。

当你对房子的唯一记录是在一张特定的纸上时,就会发生内存泄漏,而你破坏了它并失去了房子的踪迹。

悬空指针是不整洁且有风险的,因为如果有人跟随它,就会发生坏事,但这不是一个直接的错误。即使是泄漏也不是直接的错误。

一个唯一的 ptr 对象是同一个地址——同样的文字——但是写在一个神奇的宝石上。当宝石被摧毁时,房子也被摧毁。

这使得在不泄漏唯一 ptr 的情况下很难泄漏资源。而且因为资源的所有者很清楚——它是唯一的 ptr——它使得唯一的 ptr 不太可能悬空,因为每个人都应该知道只有通过摧毁唯一的 ptr(粉碎)来清理资源(摧毁房子)宝石)。

因此,清除人/动物向量会破坏独特的 ptrs(宝石),从而自动破坏房屋(人和动物)。

vector-of-vector-of-pointers 仍然存在,但充满了悬空指针。然后清除它成为一个好主意。但是它的存在并没有直接的危害。在之前或之后清除它对人或动物的寿命没有影响,因为它只是一组说明动物在结构化表格中的位置的注释。

【讨论】:

  • 我觉得我在读一个童话故事,魔法宝石什么的!但非常清楚地说明了——谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-03-31
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多