2011-01-29 47 views
6

Esta pregunta es continuación de my question.std :: vector <std::string> crash

Aquí está el código problemático.

ah:

#include <string> 
#include <vector> 

std::vector<std::string> foo(); 

a.cpp

#include "a.h" 

std::vector<std::string> foo() 
{ 
    std::vector<std::string> v; 
    return v; 
} 

y finalmente main.cpp:

#include "a.h" 
#include <iostream> 

int main() 
{ 
    std::vector<std::string> s = foo(); 

    return 0; 
} 

Compilación de la siguiente manera (main.cpp se compila con la bandera STL depuración) :

g++ -c a.cpp 
g++ -D_GLIBCXX_DEBUG main.cpp a.o 

Cuando se ejecuta a.out, bloquea el proceso:

Core was generated by `./a.out'. 
Program terminated with signal 11, Segmentation fault. 
#0 0x00007fe355998c43 in __gnu_debug::_Safe_iterator_base::_M_detach_single()() from /usr/lib64/libstdc++.so.6 
(gdb) bt 
#0 0x00007fe355998c43 in __gnu_debug::_Safe_iterator_base::_M_detach_single()() from /usr/lib64/libstdc++.so.6 
#1 0x00007fe355999ebc in __gnu_debug::_Safe_sequence_base::_M_detach_all()() from /usr/lib64/libstdc++.so.6 
#2 0x0000000000400cac in __gnu_debug::_Safe_sequence_base::~_Safe_sequence_base()() 
#3 0x0000000000400cc6 in __gnu_debug::_Safe_sequence<std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::~_Safe_sequence()() 
#4 0x0000000000400ce7 in std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector()() 
#5 0x0000000000400c35 in main() 

Mi gcc:

Using built-in specs. 
Target: x86_64-suse-linux 
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.4 --enable-linux-futex --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux 
Thread model: posix 
gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux) 

Respuesta

1

En su pregunta anterior, hace referencia a la documentación de GCC aquí: http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html. Esa documentación indica que el libstdc GCC++ "apoya recompilación por usuario", y lo define de la siguiente manera:

por uso recompilación: El usuario debe volver a compilar las partes de su aplicación y las bibliotecas de C++ que depende donde debería ocurrir la depuración, y cualquier otro código que interactúe con esos contenedores. Esto significa que un conjunto de unidades de traducción que accede a una instancia de contenedor estándar particular puede compilarse en modo de lanzamiento (sin comprobación) o en modo de depuración (comprobación completa), pero todas deben compilarse de la misma manera; una unidad de traducción que no ve que la instancia de contenedor estándar no necesita ser recompilada. Esto también significa que una unidad de traducción A que contiene una instanciación particular (por ejemplo, std :: vector) compilada en modo liberación puede vincularse con una unidad de traducción B que contiene la misma instanciación compilada en modo de depuración (una característica no presente con recompilación parcial) Si bien este comportamiento es técnicamente una violación de la Regla de una sola definición, esta habilidad tiende a ser muy importante en la práctica. El modo de depuración libstdC++ admite este nivel de recompilación.

de la compilación por unidad, que es lo que estamos tratando de hacer aquí, que dice:

Creemos que este nivel de recompilación de hecho no es posible si tenemos la intención de suministrar segura iteradores, deje la semántica del programa sin cambios, y no regresión en el rendimiento en modo de lanzamiento ....

Por lo tanto, mi respuesta a su pregunta anterior no era del todo precisa, y me disculpo. Le agregué un apéndice para corregirlo, con lo que espero que sea una sugerencia útil sobre cómo resolver el problema de las múltiples bibliotecas allí.

12

Su problema está pasando -D_GLIBCXX_DEBUG sólo a.cpp. Este indicador agrega información de depuración adicional a las estructuras de STL, y como tal, su uso debe ser constante en todos los archivos de su proyecto. De lo contrario, los archivos diferentes no están de acuerdo con el diseño de la memoria de std::vector y std::string, lo que da como resultado un comportamiento indefinido (un bloqueo, en su caso).

+0

Esto también es lo que entiendo.Entonces, ¿cómo comentarías las respuestas a mi pregunta? Http://stackoverflow.com/questions/4764048/stl-and-release-debug-library-mess. ¿No entendí mal las respuestas o mi pregunta no es clara/correcta? – dimba

+2

Para que quede claro, en general, las banderas deben establecerse de una vez por todas y aplicarse consistentemente a todo el conjunto de archivos que desea compilar. –

+0

@Matthieu Puede referirse también al comentario anterior – dimba

Cuestiones relacionadas