2009-09-14 7 views
6

Ho uno std::vector<uint8_t> che contiene stringhe a offset specifici. Ecco una discarica accorciata:std :: string :: assign() causa segfault

... 
@128 00 00 00 00 00 00 00 00 73 6F 6D 65 74 68 69 33 ........somethin 
@144 38 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ng.............. 
@160 00 00 00 00 00 00 00 00 31 2E 32 2E 33 00 00 00 ........1.2.3... 
@176 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 
... 

Sto cercando di estrarre i dati all'offset 136 e metterlo in un std::string:

std::string x; 
x.assign(vec.begin()+136, vec.begin()+168); 

Questo, tuttavia, fa sì che la mia domanda di segmentation fault. Ora sono abbastanza nuovo allo sviluppo del software sotto Linux, ma so come iniziare la mia app in GDB e ottenere un backtrace, e rintracciato il problema qui:

(gdb) backtrace 
#0 0xb7536d78 in ??() from /lib/i686/cmov/libc.so.6 
#1 0xb7538cd5 in malloc() from /lib/i686/cmov/libc.so.6 
#2 0xb7708957 in operator new(unsigned int)() from /usr/lib/libstdc++.so.6 
#3 0xb76e4146 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)() from /usr/lib/libstdc++.so.6 
#4 0xb76e63b0 in std::string::_M_mutate(unsigned int, unsigned int, unsigned int)() from /usr/lib/libstdc++.so.6 
#5 0xb76e654a in std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int)() from /usr/lib/libstdc++.so.6 
#6 0x0806d651 in std::string::_M_replace_dispatch<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0xbfffe464, __i1=..., __i2=..., __k1=..., __k2=...) at /usr/include/c++/4.3/bits/basic_string.tcc:637 
#7 0x0806d26e in std::string::replace<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:1390 
#8 std::string::assign<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (
    this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:958 
#9 myclass::somemethod (this=0x811c730, vec=...) at myclass.cpp:135 

stampa vec.size() ritorna 200 e anche oltre looping il vettore e la stampa dei dati non mi causano problemi (esattamente sopra lo snippet che si blocca!).

Sto compilando in Debian con g ++ 4.3.4. Qualche suggerimento su quale potrebbe essere questo problema?

risposta

13

È probabile che non ci sia corrispondenza libera/eliminazione da qualche altra parte nel codice che sta ritardando il sintomo fino ad ora. Quando si utilizza la memoria liberata, il sistema operativo è libero di continuare finché lo ritiene opportuno.

Provare a eseguire il programma in valgrind. valgrind usa il proprio malloc e gratuitamente in modo che possa avvisarti di notizie e cancellazioni errate. Assicurati di compile without optimisations e con -g :

g++ -g main.cc -o binary 
valgrind --leak-check=full ./binary 

Assicurarsi di non creare un puntatore da una variabile stack che va fuori di portata. Ad esempio, questo è un errore comune tra gli sviluppatori più recenti:

int *foo() { 
    int a = 0; 
    // do something to a here 
    return &a; 
} 

Come è andata fuori portata, si restituisce un puntatore alla memoria liberata.


Chi -g, dalla pagina di manuale: Produrre le informazioni di debug nel formato del sistema operativo nativo (coltellate, COFF, XCOFF, o NANO 2). GDB può funzionare con queste informazioni di debug.

+0

Poiché la memoria è già presente in un vettore, dubito che il problema sia dovuto alla mancata corrispondenza di nuova/eliminazione. –

+0

La cosa divertente è che, se lo eseguo tramite valgrind, non si verifica alcun segfault ... –

+0

Per non approfondire le specifiche, stavo tentando di eliminare una struttura addrinfo inesistente. stavo chiamando freeaddrinfo() ma non impostando il puntatore su NULL, questo mi ha fatto provare a cancellare di nuovo la stessa memoria. –