2011-01-29 22 views
6

Questa domanda è la continuazione di my question.std :: vector <std::string> crash

Ecco il codice problematico.

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

e infine main.cpp:

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

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

    return 0; 
} 

compilazione come segue (main.cpp viene compilato con bandiera STL debug) :

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

Quando si esegue a.out, blocca il processo:

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() 

mio 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) 

risposta

1

Nella domanda precedente, si fa riferimento alla documentazione GCC qui: http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html. Tale documentazione afferma che il libstdc GCC++ "supporta per utente ricompilazione", e definisce come segue:

Per usare ricompilazione: L'utente deve ricompilare le parti della sua applicazione e le librerie C++ da cui dipende dove dovrebbe verificarsi il debug e qualsiasi altro codice che interagisce con tali contenitori. Ciò significa che un insieme di unità di traduzione che accede a una particolare istanza contenitore standard può essere compilato in modalità di rilascio (senza controllo) o in modalità di debug (controllo completo), ma deve essere compilato allo stesso modo; un'unità di traduzione che non vede che l'istanza contenitore standard non deve essere ricompilata. Ciò significa anche che un'unità di traduzione A che contiene una particolare istanziazione (ad esempio, std :: vector) compilata in modalità di rilascio può essere collegata a un'unità di traduzione B che contiene la stessa istanza compilata in modalità di debug (una funzionalità non presente con la ricompilazione parziale)). Sebbene questo comportamento sia tecnicamente una violazione della regola della One Definition, questa capacità tende ad essere molto importante nella pratica. La modalità di debug libstdC++ supporta questo livello di ricompilazione.

di per-unità di compilazione, che è quello che stai cercando di fare qui, si dice:

Crediamo che questo livello di ricompilazione non è infatti possibile se abbiamo intenzione di fornire al sicuro iteratori, lasciare invariata la semantica del programma e non regredire in prestazioni in modalità rilascio ....

Pertanto, la mia risposta alla domanda precedente non era del tutto accurata, e mi scuso. Ho aggiunto un addendum per correggerlo, con quello che spero sia un suggerimento utile su come risolvere il problema di multi-libreria.

12

Il tuo problema sta passando -D_GLIBCXX_DEBUG solo a.cpp. Questo flag aggiunge ulteriori informazioni di debug alle strutture STL e pertanto l'utilizzo deve essere coerente su tutti i file del progetto. In caso contrario, diversi file non sono d'accordo sul layout di memoria di std::vector e std::string, con conseguente comportamento non definito (un arresto anomalo nel tuo caso).

+0

Questo è anche quello che capisco.Quindi, come commenteresti le risposte alla mia domanda http://stackoverflow.com/questions/4764048/stl-and-release-debug-library-mess. Non ho frainteso le risposte o la mia domanda non è chiara/corretta? – dimba

+2

Per essere chiari, in generale, i flag devono essere impostati una volta per tutte e applicati in modo coerente all'intero insieme di file che si desidera compilare. –

+0

@Matthieu Per favore, puoi anche fare riferimento a uno sopra sopra – dimba

Problemi correlati