将(string,object *)插入哈希表(C ++)

时间:2009-10-30 18:36:07

标签: c++ hashmap

这个问题是我的previous question与创建哈希表以将字符串键和指针存储为数据的过程。当我尝试在哈希表中添加条目时,我在构建后遇到了一个seg错误。我仍然对适当的语法感到困惑。

我目前有(感谢之前的海报):

// Simulation.h
#include <ext/hash_map>
using namespace __gnu_cxx;
...
typedef struct { size_t operator()( const string& str ) const 
  { return __gnu_cxx::__stl_hash_string( str.c_str() ); } } strhash;

struct eqstr {
  bool operator()(string s1, string s2) const {
   return ( s1.compare(s2) == 0 );
  }
};
....
hash_map< string, Strain *, strhash, eqstr > strainTable;

在我的Simulation构造函数中,我有:

// Simulation.cpp
Simulation::Simulation() : ... {
  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 );
  strainTable[ MRCA ]= firstStrainPtr; // <-- Hash table initialization
  ....
}

这似乎工作正常。尝试以下插入时出现seg错误:

void Simulation::updateSimulation( double t ) {
   ....
   // Add mutants to liveStrains() and strainTable
   vector< Strain * >::const_iterator mItr = newMutants.begin();
   for ( mItr = newMutants.begin(); mItr != newMutants.end(); ++mItr ) // for each mutant in deme
{
  string mutantSeq = ( *mItr )->getSequence();
  cout << "mutantSeq is " << mutantSeq << endl; // <-- This is fine
  liveStrains.push_back( *mItr );
  strainTable[ mutantSeq ] = *mItr; // <-- Seg fault happens here
}
  newMutants.clear();
  ....  
}

阅读SGI documentation中关于运算符[]的第三个音符,这似乎应该没问题。怎么了?我正在考虑切换到地图容器,以节省调试时间......

更新

关于初始化的事情似乎是错误的。当我到达

strainTable[ mutantSeq ] = *mItr;

调试器报告“EXC_BAD_ACCESS”并跳转到

_Node* __first = _M_buckets[__n];
hashtable.h的

3 个答案:

答案 0 :(得分:1)

作为一种诊断方法,您实际上在线上执行了2条指令:

  1. strainTable中查找,返回引用
  2. 取消引用迭代器
  3. 为参考分配值
  4. 您可能希望采用Divide and Conquer方法:

      strainTable[ mutantSeq ] = *mItr; // <-- Seg fault happens here
    

    变为

      Strain*& aReference = strainTable[ mutantSeq ];
      Strain* const aPtr = *mItr;
      aReference = aPtr;
    

    (这是一般建议)

    发生seg故障的哪一行?是否可以拥有堆栈的10个第一帧?

    在查找Google时,我提出了bug report,这表明hash_map可能存在问题......

    如果可能的话,你可能最好使用unordered_map,因为它清楚地表明没有时间修复被视为旧容器的hsah_map(这是2005年......)。请注意,如果您使用GCC 4.x(不确定3.x)

    ,它应该可用

    主要优势是hash结构和comparison predicate已经适用于std::string,因此您甚至不必自己实施它们:)

    因此,如果你的编译器中有这个,那么你要做的就是写下这个:

    #include <tr1/unordered_map>
    
    typedef std::tr1::unordered_map<std::string, Strain*> strain_hash_map;
    

答案 1 :(得分:0)

我看不出这个代码有什么坏处。错误必须在另一个地方。也许是(* mItr) - > getSequence()的值,即给出无效的字符串,或类似的东西。

作为优化,operator()可以取字符串const&amp;而不仅仅是字符串。

答案 2 :(得分:0)

令人尴尬的“解决方案”是我发现我没有在类头文件中声明二维数组的完整大小。当我在构造函数中初始化数组时,碰巧覆盖了哈希表的一些空间。

感谢这里的建议,我现在转到了std :: tr1 :: unordered_map!