2011-01-29 31 views
6

この質問は続きますmy questionです。std :: vector <std::string>クラッシュ

ここに問題のコードがあります。

ああ:

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

、最終的にmain.cppに次のよう

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

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

    return 0; 
} 

コンパイル(main.cppには、STLのデバッグフラグでコンパイルされています) :

10のa.outを、実行中のプロセスがクラッシュ:

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

マイ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) 

答えて

1

あなたの前の質問では、ここでGCCのドキュメントを参照しています:http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html

ごとの使用の再コンパイル:ユーザーは自分のアプリケーションの部分と、それが依存C++ライブラリを再コンパイルする必要があります資料には、GCCのlibstdC++「は、ユーザーごとの再コンパイルをサポートしています」、と次のように定義されていることを述べてデバッグが行われる場所、およびそれらのコンテナと相互作用する他のコードが含まれます。つまり、特定の標準コンテナインスタンスにアクセスする翻訳ユニットのセットは、リリースモード(チェックなし)またはデバッグモード(フルチェック)でコンパイルできますが、すべて同じ方法でコンパイルする必要があります。その標準のコンテナインスタンスが再コンパイルされる必要がないことを認識しない変換単位があります。これはまた、リリースモードでコンパイルされた特定のインスタンス化(std :: vectorなど)を含む変換ユニットAが、デバッグモードでコンパイルされた同じインスタンシエーションを含む変換ユニットB(部分再コンパイルでは存在しない機能)。この動作は技術的には1つの定義ルールに違反しますが、この能力は実際には非常に重要になる傾向があります。 libstdC++デバッグモードでは、このレベルの再コンパイルがサポートされています。あなたがここで何をしようとしてで単位当たりのコンパイルの

、それは言う:

私たちは安全な供給しようとする場合には、再コンパイルのこのレベルは可能ではないという事実であることを信じていますイテレータは、プログラムのセマンティクスを変更しないで放しておいて、リリースモードでのパフォーマンスが回帰しないようにします。

したがって、以前の質問に対する私の答えは完全ではなく、謝罪します。私はそれを修正するための補足を追加しました。そこにあるマルチライブラリの問題を解決する方法についての有用な提案です。

12

あなたの問題がa.cpp-D_GLIBCXX_DEBUGを通過しています。このフラグはSTL構造体に追加のデバッグ情報を追加するので、その使用法はプロジェクト内のすべてのファイルにわたって一貫していなければなりません。そうでないと、異なるファイルがstd::vectorstd::stringのメモリレイアウトに一致せず、結果として未定義の動作が発生します(あなたの場合はクラッシュします)。

+0

これも私が理解しているものです。だから、あなたは私の質問http://stackoverflow.com/questions/4764048/stl-and-release-debug-library-messへの回答をどのようにコメントしますか?私は答えを誤解していないか、私の質問は明確ではない/正しいですか? – dimba

+2

一般的に、フラグは一度設定しておき、コンパイルしたいファイル全体に一貫して適用する必要があります。 –

+0

@Matthieu上記のコメントを参照することもできます – dimba

関連する問題