c++ - Segfault en la enésima interación a través de std:: map
segmentation-fault stdmap (1)
Esto no es solo una prueba de presencia
unsigned short* test_array = site_depths["lcl_NM_000999"];
pero también inserta un nodo en site_depths, pero con un puntero nulo en el second
miembro.
El código también confía en que el start
y el end
estén siempre dentro del rango del tamaño de la matriz dado por el size
. ¡No estaría de más validar eso!
Solución: consulte la publicación de Bo Persson y mi comentario a continuación.
Estoy obteniendo un error de segmentación con mi mapa. Lo que me confunde es que las iteraciones n-1 sobre las teclas funcionan pero luego fallas seg en la enésima iteración. Para aumentar la confusión, el valor de clave con el que falla la iteración seg se encuentra (con un iterador) en la iteración anterior e incluso antes en el código.
Traté de perfilar el fallo seg con valgrind, sin embargo, recibo un bucle infinito del mensaje, "la señal 11 se cayó del hilo 0". Por lo tanto, valgrind no es muy útil.
El mapa segmentado se denomina site_depths. Aquí es cómo se insertan los valores:
map<string,unsigned short*> site_depths;
map<string,unsigned int>::iterator it;
map<string,unsigned short*>::iterator insert_it;
unsigned int size = 0;
string key = "";
// go through each key pair of CHROM_SIZES to build the site_depth map
for (it=CHROM_SIZES.begin(); it != CHROM_SIZES.end(); it++) {
key = it->first;
size = it->second;
unsigned short *array = new unsigned short[size];
insert_it = site_depths.end();
site_depths.insert(insert_it, pair<string,unsigned short*>(key,array));
}
Lo revisé para asegurarme de que todos los valores añadidos funcionan. Tanto la clave como el tamaño se imprimen en la consola.
Inmediatamente después, pruebo para ver si find () y [] acceden al trabajo sobre el valor clave que seg falla (esto también funciona):
cout << "schill found: " << site_depths.find("lcl_NM_000999")->first << endl;
unsigned short* test_array = site_depths["lcl_NM_000999"];
Luego, cuando analizo el archivo de texto, segmentará el error en find () o si lo recomiendo, en el acceso []:
string line;
string chromosome;
unsigned int start;
unsigned int end;
unsigned int i;
char* values[3];
unsigned short* sites;
map<string,unsigned short*>::iterator iter_end = site_depths.end();
while (getline(in,line)) {
//use C strtok to tokenize the line
char cstr[line.size()+1];
strcpy(cstr,line.c_str());
char *pch = strtok(cstr, " ");
// tokenize three columns
for (i=0; i<3 || pch != NULL; i++) {
values[i] = pch;
pch = strtok(NULL, " ");
}
chromosome = values[0];
start = atoi(values[1])-1; //must subtract 1 to correspond to 0 index
end = atoi(values[2])-1;
// get appropriate array pointer
if (site_depths.find(chromosome) == iter_end) {
cerr << "WARNING: Chromosome name in Input file does not match .len file." << endl;
cerr << " Exiting script." << endl;
exit(EXIT_FAILURE);
}
sites = site_depths[chromosome];
// increment over range
for (i=start; i<end; i++) {
sites[i]++;
}
}
El caso donde segfaults es en la clave "lcl_NM_000998", tratando de encontrar la clave "lcl_NM_000999". Esto no tiene sentido ya que la iteración getline () anterior encuentra el valor clave "lcl_NM_000998". Lo he verificado para asegurarme de que este es el caso al iterar manualmente a través del mapa.
Lo he comprobado para asegurarme de que mi código anterior no fallaba en el código anterior, pero el tokenizing se ve bien. Mi código siempre segfaults en esta ubicación en mi caso de prueba. ¿Alguien tiene ideas?