【问题标题】:C++ vector at(#) replacement clean up memory?C++ 向量 at(#) 替换清理内存?
【发布时间】:2021-12-21 02:14:01
【问题描述】:

编译库的痛苦在于永远不知道内存是如何管理的。 我被引导相信向量的元素被放置在堆上,除非明确告知不要这样做。

被放在堆上,不用的时候显然需要删除,好像删除vector对象的时候会出现这种情况。

问题是当at(#)或operator[]被调用时,它会删除被替换的内存吗?

例如:

std::vector<string> secretlyAnArray(5);
secretlyAnArray.at(0) = std::string("Does this memory leak?");
secretlyAnArray.at(0) = std::string("When I overwrite the object?")

很高兴学习更好的方法来替换向量的特定索引处的数据,或者只是指向解释它的文档。

编辑 2: 在非常感谢 Anis 和 Daniel 的帮助之后;似乎 at(#) 返回一个引用,然后应用标准引用规则而不是受向量的行为支配。

【问题讨论】:

  • at 返回给定位置的对象的引用,因此您的对象将被分配或移动
  • @AnisBelaid 啊,所以它只是更新数据而不是替换对象?因此,如果您使用的是自定义类,那么如果您有一个复制构造函数,而不是分配和移动运算符,它会严重中断吗? (如果浅拷贝还不够)
  • 是的,它不起作用,也没有内存泄漏,因为临时对象在范围之外被破坏
  • “我被引导相信向量被放置在堆上,除非明确告知不要这样做。” — 向量对象放置在您创建它的任何位置。在自动存储持续时间的情况下(基本上是函数本地非静态变量),它将在典型实现的堆栈上。但是向量元素总是在堆上(至少使用默认分配器)。
  • 一般来说,如果您使用过new,则需要使用delete(或将您的对象传递给可以为您执行此操作的对象),否则已分配内存的类应该释放它自动销毁

标签: c++ memory vector


【解决方案1】:
std::vector<std::string> secretlyAnArray(5);
secretlyAnArray.at(0) = std::string("Does this memory leak?");
secretlyAnArray.at(0) = std::string("When I overwrite the object?")

此代码将std::string 类型的对象分配给std::string 类型的另一个对象。 std::vector 本身根本不参与这项任务。在这里,它只是提供对目标(分配给)对象的引用。

赋值对给定类型的作用取决于它的定义。没有通用的答案。例如,对于std::string,当您复制/移动分配时,目标对象的原始内容(其字符串)需要“销毁”。 std::string 为你做,所以,你不需要关心它。这意味着如果字符串是“长”的(关于短字符串优化;SSO),如果需要,内存将被正确释放。

【讨论】:

  • 是的,关于向量,你是 100% 正确的。我将更改问题中的措辞,因为我确实指的是向量的元素。有趣的;当您谈论被销毁的内存时,您是指类析构函数还是更抽象的东西,例如智能指针管理何时调用其析构函数的方式?或者更简单地说,在重新分配值之前,您是否需要对向量的元素调用 delete?
  • 是否调用 vector.at(type) 等同于调用: type::operator=(const type& other) 或 type::operator=(const type&& other) 取决于是否给定 L 或 R输入值?
  • @Bellona 同样,没有通用答案。例如,对于赋值操作的copy-and-swap 解决方案,涉及到析构函数调用。这应该释放对象拥有的所有资源。但是,对于std::string,如果目标对象的容量能够存储源对象拥有的字符串,则不需要(取消)分配。赋值运算符可以使用现有分配的缓冲区将字符串复制到。
  • “在重新分配值之前,您是否需要对向量的元素调用 delete?” — 不,您不能显式地“删除”向量的元素。矢量会为您管理其元素,包括在需要时将其销毁。
  • @Bellona 不,它不等效。如前所述,vector.at() 仅返回对该元素的引用。它的内容不代表任何操作。单独调用vector.at() 没有任何效果。
猜你喜欢
  • 2010-11-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多