这个问题是我的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的。
答案 0 :(得分:1)
作为一种诊断方法,您实际上在线上执行了2条指令:
strainTable
中查找,返回引用您可能希望采用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!