Pergunta

Esta questão é uma offgrowth da minha pergunta anterior na criação de um hash mesa para chaves de cadeia de loja e os ponteiros como dados. Eu estou recebendo uma falha seg pós-construção quando eu tento adicionar entradas para a minha mesa hash. Eu ainda estou muito confuso sobre o que a sintaxe é apropriado.

Eu tenho atualmente (graças a cartazes anteriores):

// 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;

Na minha construtor Simulation, eu tenho:

// 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
  ....
}

Este parece funcionar bem. Eu recebo uma falha seg quando a seguinte inserção é tentada:

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();
  ....  
}

A leitura da terceira nota do operador [] no SGI documentação , isso parece que deve ser fino. O que há de errado? Estou pensando em mudar para um recipiente do mapa apenas para poupar tempo de depuração ...

Atualizar

Algo sobre a inicialização parece errado. Quando eu chegar

strainTable[ mutantSeq ] = *mItr;

os relatórios de depurador "EXC_BAD_ACCESS" e salta para

_Node* __first = _M_buckets[__n];

de hashtable.h.

Foi útil?

Solução

Como uma abordagem diagnóstico, você realmente tem 2 instruções executadas na linha:

  1. Lookup em strainTable, que retorna uma referência
  2. Dereferencing o iterador
  3. atribuição de um valor de referência

Aqui você pode querer ter uma abordagem Divide and Conquer:

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

Torna-se

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

(que é um conselho geral)

Em qual linha ocorre a falha seg? Seria possível ter os 10 primeiros quadros de pilha?

Enquanto olhando para cima Google, eu vim este relatório de bug , o que sugere que pode haver problemas com o hash_map ...

Você pode ser melhor fora de usar a unordered_map , se possível, como é claramente indicado que o tempo não será levado a fixação do hsah_map visto como um recipiente legado (e este era 2005 ...). Note-se que ele deve estar disponível se você usar o GCC 4.x (não tenho certeza para 3.x)

A principal vantagem é que a estrutura hash e comparison predicate já trabalho para std::string para que você não tem sequer a implementá-los a si mesmo:)

Tudo que você tem que fazer, por isso, se você tem isso em seu compilador, é escrever o seguinte:

#include <tr1/unordered_map>

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

Outras dicas

Eu não posso ver qualquer mal com este código. O erro tem que ter em outro lugar. Talvez o valor de (* Mitr) -.> GetSequence (), que está dando uma cadeia inválida, ou algo parecido

Como uma otimização, o operador () poderia levar const corda e em vez de apenas o fio de.

A "solução" embaraçoso é que eu descobri que eu não tinha declarado o tamanho natural de uma matriz bidimensional no arquivo de cabeçalho de classe. Quando eu inicializado a matriz no construtor, isso aconteceu para substituir algum do espaço para a tabela de hash.

Graças às sugestões aqui, eu agora mudou-se para um std :: tr1 :: unordered_map!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top