2011-01-29 27 views
6

To pytanie jest kontynuacją my question.std :: wektor <std::string> crash

Oto problematyczny kod.

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

wreszcie main.cpp:

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

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

    return 0; 
} 

kompilacji jak następuje (main.cpp opracowano z flagą STB debugowania) :

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

Uruchamiając a.out, awarie technologiczne:

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

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

Odpowiedz

1

W poprzednim pytaniu odwołujesz się do dokumentacji GCC tutaj: http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html. Że dokumentacja wskazuje, że libstdc GCC++ „wspiera rekompilacji per-user” i definiuje ją następująco:

per-use rekompilacji: użytkownik musi ponownie skompilować części swoich aplikacji i bibliotek C++ to zależy gdzie powinno wystąpić debugowanie i każdy inny kod, który współdziała z tymi kontenerami. Oznacza to, że zestaw jednostek tłumaczeniowych, które uzyskują dostęp do określonej standardowej instancji kontenera, może być skompilowany w trybie zwolnienia (bez sprawdzania) lub trybu debugowania (pełne sprawdzenie), ale wszystkie muszą być kompilowane w ten sam sposób; jednostka tłumaczeniowa, która nie widzi, że standardowa instancja kontenera nie musi być rekompilowana. Oznacza to również, że jednostka tłumaczeniowa A, która zawiera określoną instancję (np. Std :: vector) skompilowaną w trybie zwolnienia, może być połączona z jednostką tłumaczeniową B, która zawiera tę samą instancję skompilowaną w trybie debugowania (funkcja nieobecna przy częściowej rekompilacji). Chociaż takie zachowanie jest technicznie naruszeniem zasady "Jedna definicja", ta zdolność jest w praktyce bardzo ważna. Tryb debugowania libstdC++ obsługuje ten poziom rekompilacji.

kompilacji jednostkowej, która jest co próbujesz tu zrobić, to mówi:

Wierzymy, że ten poziom rekompilacji jest w rzeczywistości niemożliwe, jeśli zamierzamy dostarczać bezpieczne iteratory, pozostaw bez zmian semantykę programu i nie cofaj wydajności w trybie wydania ...

Tak więc moja odpowiedź na poprzednie pytanie nie była całkowicie dokładna i przepraszam. Dodałem do niego dodatek, aby poprawić to, co mam nadzieję, jest przydatną sugestią, jak rozwiązać problem z wieloma bibliotekami.

12

Twój problem przechodzi -D_GLIBCXX_DEBUG tylko a.cpp. Ta flaga dodaje dodatkowe informacje do debugowania do struktur STL i jako takie jej użycie musi być spójne dla wszystkich plików w projekcie. W przeciwnym razie różne pliki nie zgadzają się co do układu pamięci std::vector i std::string, powodując niezdefiniowane zachowanie (awaria w twoim przypadku).

+0

To też rozumiem.Więc, jak byś skomentował odpowiedzi na moje pytanie http://stackoverflow.com/questions/4764048/stl-and-release-debug-library-mess. Czy nie rozumiem źle odpowiedzi lub moje pytanie nie jest jasne/poprawne? – dimba

+2

Dla uproszczenia, ogólnie, flagi powinny być ustawione raz na zawsze i konsekwentnie stosowane do całego zestawu plików, które chcesz skompilować. –

+0

@Matthieu Czy możesz też odnieść się do komentarza powyżej powyżej – dimba

Powiązane problemy