【问题标题】:Will pointer to an element in QMap remain valid after inserting some more elements in the map?在映射中插入更多元素后,指向 QMap 中元素的指针是否仍然有效?
【发布时间】:2017-07-18 19:11:31
【问题描述】:

我有 QMap 存储对象,我想存储指向这些对象的指针以进行一些外部处理。从映射中插入/删除某些值后,指向对象的指针是否仍然有效?举例说明:

QMap <QString, QString> map;

map.insert("one", "one");
map.insert("two", "two");
map.insert("three", "three");

QString *pointer = &map["one"];
qDebug()<<*pointer;

map.insert("aaa", "aaa");
map.insert("bbb", "bbb");
qDebug()<<*pointer;

map.insert("zzz", "zzz");
map.insert("xxx", "xxx");
qDebug()<<*pointer;

是否保证pointer 在任意数量的插入/删除后将指向完全相同的对象(当然考虑到该对象没有被删除)

或者我应该考虑存储指针而不是对象?

【问题讨论】:

  • 映射中的值是按值存储的,即使在这种情况下,这意味着指针(它指向的地址)是按值存储的 For example
  • 您是否考虑过改用std::map?标准容器的失效规则有完整的文档记录,并且可以更普遍地理解。
  • This link 表示插入 QMap 不会使迭代器无效。 “如果您将项目添加到地图中,现有的迭代器将保持有效。” 可能还会保留指向现有元素的指针,但没有明确说明。

标签: c++ qt


【解决方案1】:

对您的代码进行小幅修改:

  QMap <QString, QString> map;

  map.insert("one", "one");
  map.insert("two", "two");
  map.insert("three", "three");

  QString *pointer = &map["one"];
  qDebug()<<pointer;

  map.insert("aaa", "aaa");
  map.insert("bbb", "bbb");
  pointer = &map["one"];
  qDebug()<<pointer;

  map.insert("zzz", "zzz");
  map.insert("xxx", "xxx");
  pointer = &map["one"];
  qDebug()<<pointer;

显示它看起来仍然有效。

QMap 元素在插入时进行排序。底层数据结构是一棵红黑树(至少在 Qt5 中,IIRC 在 Qt4 中是一个跳过列表)。节点显然存储在堆上而不是池上,因为它没有 reserve(space) 方法,只有在使用池时才适用。

没有充分的理由将树节点重新分配到另一个内存位置,因为通过更改叶指针值很容易重新定义树结构。

是的,只要不删除特定的键条目,指针就应该随着地图的变化而持续存在。

【讨论】:

  • 请记住 Qt 中的整个“延迟分离”魔法,它可能导致重新分配(因为下一次写入访问触发复制,即使您只分发了只读副本)。即使结构本身在单实例操作期间不会移动/复制,但在复制后会移动/复制,并且在源中也会这样做!
猜你喜欢
  • 2019-04-08
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多