2009-09-14 13 views
6

J'ai un std::vector<uint8_t> qui contient des chaînes à des décalages spécifiques. Voici une décharge raccourci:std :: string :: assign() provoque la 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 ................ 
... 

Je suis en train d'extraire les données à l'offset 136 et le mettre dans un std::string:

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

Cependant, cela provoque ma demande segfault. Maintenant, je suis assez nouveau au développement de logiciels sous Linux, mais je ne sais comment commencer mon application dans GDB et obtenir un backtrace, et dépisté le problème ici:

(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 

impression vec.size() retourne 200 et boucle même sur le vecteur et l'impression des données ne me pose aucun problème (exactement au-dessus de l'extrait qui se bloque!).

Je compile dans Debian avec g ++ 4.3.4. Des indications sur ce que pourrait être ce problème?

Répondre

13

Il y a probablement un décalage/suppression non concordant ailleurs dans votre code qui retarde le symptôme jusqu'à maintenant. Lorsque vous utilisez libéré de la mémoire, le système d'exploitation est libre de continuer aussi longtemps qu'il le souhaite. Essayez d'exécuter le programme dans valgrind. valgrind utilise son propre malloc et gratuit afin de vous avertir des nouvelles et des suppressions incorrectes. Assurez-vous de compile without optimisations et -g :

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

Assurez-vous que vous ne créez pas un pointeur d'une variable de pile qui est hors de portée. Par exemple, ceci est une erreur commune parmi les développeurs les plus récents:

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

En est sorti de la portée, vous retournez un pointeur vers la mémoire libérée.


A propos -g, de la page de manuel: Produire des informations de débogage au format natif du système d'exploitation (coups de couteau, COFF, XCOFF ou NAIN 2). GDB peut fonctionner avec ces informations de débogage.

+0

Étant donné que la mémoire est déjà dans un vecteur je doute que le problème réside dans new/delete mismatch. –

+0

La chose amusante est, que si je l'exécute à travers valgrind, aucun segfault se produit ... –

+0

Pour ne pas aller trop loin dans les détails, j'essayais de supprimer une structure addrinfo inexistante. J'appelais freeaddrinfo() mais ne définissant pas le pointeur sur NULL, cela m'a amené à essayer de supprimer le même mémoire à nouveau. –

Questions connexes