【问题标题】:Basic questions: Pointers to objects in unordered_maps (C++)基本问题:指向 unordered_maps 中对象的指针 (C++)
【发布时间】:2009-10-31 00:06:15
【问题描述】:

我是 C++ 编程的新手,非常感谢那些不需要太多先验知识的回复。

感谢这里的建议,我创建了一个无序地图:

typedef std::tr1::unordered_map<std::string, Strain*> hmap;

此映射中的数据是指向 Strain 类实例的指针。一旦创建了这些实例,我就创建指向它们的指针,然后将这些指针添加到我的哈希表 (hmap strainTable) 和另一个向量 (vector liveStrains),例如,

string MRCA;
for ( int b = 0; b < SEQ_LENGTH; b++ ) {
 int randBase = rgen.uniform(0,NUM_BASES); 
 MRCA.push_back( BASES[ randBase ] );
}
Strain * firstStrainPtr;
firstStrainPtr = new Strain( idCtr, MRCA, NUM_STEPS );
liveStrains.push_back( firstStrainPtr ); 
strainTable[ MRCA ]= firstStrainPtr;

Strain 类的实例永远不会被删除,指向它们的指针也不会从 strainTable 中删除。指针偶尔会在vector liveStrains 和vector deadStrains 之间移动,但是一旦在strainTable 上,它们就会一直在strainTable 上。

这是犹太洁食吗?只要底层实例永远不会被销毁,添加到它们的指针会保持不变吗?

我应该总是能够通过使用,例如,对于第一个条目,从 strainTable 中的指针获取成员属性,这也是正确的吗,

 hmap::const_iterator itr1 = strainTable.begin();
 int id = (itr1->second)->getStrainID();

我发现一段时间后,我的 strainTable 中的指针指向垃圾。

【问题讨论】:

  • 除非您对应变指针调用 delete,否则它们不会被释放,但可能还有其他事情,例如在未分配的区域中写入。为 Strain 编写析构函数并编写一些调试打印语句或抛出异常以查看调用堆栈,如果您怀疑 Strain 以某种方式被释放。

标签: c++ unordered-map


【解决方案1】:

指向使用new 分配的任何对象的指针将保持有效,直到您对该对象调用delete。指针可以随意复制,只要底层对象没有被删除就有效。

其次,是的,您可以通过容器迭代器从存储的指针访问对象属性是正确的。但始终检查以确保 hmap::find() 的返回值不等于 hmap::end()。

所以你描述的很好。现在,至于为什么您的 strainTable 中的指针最终指向垃圾,我不能说没有更多细节。你确定你没有在任何地方删除任何对象吗?您确定当您将指针从一个向量复制到另一个向量时,您的操作正确吗?

【讨论】:

  • 谢谢。我没有意识到检查 hmap::find() != hmap::end() 会很小心。稍后我将使用调试器仔细检查我的代码,看看奇怪的地方是从哪里开始的。因为我不叫“删除”,所以我很确定我没有删除任何东西,但我的指针很可能会搞砸。我将重组哈希表以使用 Strain 数据(而不是 Strain * ),看看这是否有帮助。
【解决方案2】:

如果您从未delete 他们,那么指针仍然可以。另一方面,您可能希望让事情变得更整洁,并为整个 shebang 使用标准容器。

typedef std::tr1::unordered_map<std::string, Strain> hmap;
typedef std::tr1::unordered_map<std::string, hmap::iterator> weakhmap;

hmap strainTable;
weakhmap liveStrains;
Strain firstStrain( idCtr, MRCA, NUM_STEPS );
strainTable[MRCA] = firstStrain;
liveStrains[MRCA] = strainTable.find(MRCA);

【讨论】:

  • 天哪,这很有道理。我最初有 vector liveStrains(对于 deadStrains 也是一样),然后我意识到我需要这个哈希映射,所以我切换到 liveStrains 的指针——但是将 Strain 对象保留在哈希表中要好得多。也感谢您显示语法。
  • 附注我需要将 liveStrains 作为向量,因为我在模拟中对其进行了多次迭代——我认为在这种情况下向量会比 unordered_map 更快。
  • 是的,当然,std::vector&lt;hmap::iterator&gt; 也可以,如果您需要的话。
  • 其实我有点担心如果表大小发生变化,指针和迭代器会失效...我想我还是坚持unordered_map<:string strain> 格式。
  • 根据标准:重新散列使迭代器无效,更改元素之间的顺序,并更改出现在哪些桶中的元素,但不会使指针或对元素的引用无效。所以不要存储迭代器,但你可以使用 unordered_map&lt;std::string, Strain&gt; 并将指针存储在向量中。
猜你喜欢
  • 2018-10-02
  • 1970-01-01
  • 2010-10-13
  • 2019-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多