【问题标题】:Can std::string reallocation invalidate pointer to heap?std::string 重新分配可以使指向堆的指针无效吗?
【发布时间】:2015-04-26 17:50:54
【问题描述】:

我的问题是关于以下场景:

std::string *ps = new std::string();
*ps = aVeryLargeString;

根据我的经验,通常发生的情况是 aVeryLargeString 超出了 *ps 的容量,因此 *ps 分配了额外的内存,保持起始位置相同。 所以 ps 仍将指向新字符串内存中的位置是一样的。

但是,如果该内存位置没有足够的连续空间会发生什么?重新分配是否会将字符串移动到完全不同的位置,从而使指针无效?

【问题讨论】:

  • std::string 有一个内部指针。如果需要重新分配,内部指针会改变;您指向std::string 的指针不会。这几乎就像你有一个指向指针的指针。
  • 事实上,它正是就像你有一个指向指针的指针。
  • 事实上,它有一个指向指针的指针。加上一些额外的结构信息。
  • 其实正是有一个指向指针的指针。
  • 我想我可能已经打破了这其中的可笑之处。我很抱歉。

标签: c++ string pointers heap-memory invalidation


【解决方案1】:

根据我的经验,通常发生的是 aVeryLargeString 超过*ps的容量,所以*ps分配额外的内存,保持 起始位置相同。

不,这通常不是真的。当你超过容量时,字符串使用它的分配器来分配一个完全不同的块(大小是之前容量的一些因素),并复制字符。除非您保留指向字符串实际字符的指针或引用(例如通过&(*ps)[0]ps->c_str()),而不是指向字符串对象本身的指针(这就是ps 的含义),否则您不要不用担心这个。

所以 ps 仍然会指向新字符串,因为内存中的位置是 一样的。

ps 不会也不会受到对它指向的字符串 (*ps) 的操作的任何影响(显然不包括表现出未定义行为的操作,这可能会产生任何影响)。

【讨论】:

  • 对,我想我明白了,如果我错了,请纠正我:ps 指向一个字符串,它本身有一个 char 数组成员来存储原始数据。当我分配给 ps 时,它会创建一个新的 char 数组,并使用新的更新字符串 char 数组成员,而 ps 保持不变?
  • @JamesLens:当你分配给ps?或者当你分配给*ps?当您分配给ps 时,很少发生。只是一个指针分配,如果您没有它的副本,则会发生内存泄漏。当你分配给*ps时,就像你说的那样。
  • @JamesLens: “如你所说” -- 让我收回这句话。当您分配给*ps 时,它会调用std::string 的赋值运算符,这可能会创建一个新的字符数组,或者如果有足够的空间来复制另一个字符串的字符,它可能只是重用已有的字符数组.
猜你喜欢
  • 1970-01-01
  • 2020-09-18
  • 2013-01-29
  • 1970-01-01
  • 2020-09-05
  • 2023-04-09
  • 1970-01-01
  • 2010-12-16
相关资源
最近更新 更多