Вопрос

Этот вопрос является результатом моего предыдущий вопрос о создании хэш-таблицы для хранения строковых ключей и указателей в качестве данных.Я получаю ошибку 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.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, кажется, что все должно быть в порядке.Что случилось?Я подумываю о переходе на контейнер map просто для экономии времени отладки...

Обновить

Что-то в инициализации кажется неправильным.Когда я доберусь до

strainTable[ mutantSeq ] = *mItr;

отладчик сообщает "EXC_BAD_ACCESS" и переходит к

_Node* __first = _M_buckets[__n];

из хэш-таблицы.h.

Это было полезно?

Решение

Как подход к диагностике, у вас на самом деле есть 2 инструкции, выполняемые в строке:

  1. Поиск в strainTable, который возвращает ссылку
  2. Разыменование итератора
  3. Присвоение значения ссылке

Здесь вы, возможно, захотите воспользоваться Divide and Conquer подход:

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

Становится

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

(это общий совет)

На какой линии возникает ошибка seg ?Возможно ли было бы иметь 10 первых кадров стека ?

Просматривая Google, я наткнулся на следующее отчет об ошибке, что наводит на мысль о возможных проблемах с hash_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;

Другие советы

Я не вижу ничего плохого в этом коде.Ошибка должна быть в другом месте.Возможно, значение (* mItr)-> getSequence(), которое выдает недопустимую строку, или что-то в этом роде.

В качестве оптимизации operator() мог бы принимать string const& вместо просто string .

Смущающее "решение" заключается в том, что я обнаружил, что не объявил полный размер двумерного массива в файле заголовка класса.Когда я инициализировал массив в конструкторе, случилось так, что часть пространства для хэш-таблицы была перезаписана.

Благодаря приведенным здесь предложениям, теперь я перешел к std::tr1::unordered_map!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top