2011-01-29 31 views
6

यह प्रश्न my question की निरंतरता है।std :: वेक्टर <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 एसटीएल डिबगिंग ध्वज के साथ संकलित किया गया है) :

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

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

मेरे जीसीसी:

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

अपने पिछले प्रश्न में, आप यहां जीसीसी दस्तावेज का संदर्भ देते हैं: http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html। यही कारण है कि प्रलेखन कहा गया है कि जीसीसी libstdC++ "प्रति-उपयोगकर्ता रखता का समर्थन करता है", और यह परिभाषित करता है इस प्रकार है:

प्रति उपयोग रखता: उपयोगकर्ता अपने के कुछ हिस्सों या उसके आवेदन और सी ++ पुस्तकालयों उस पर निर्भर पुन: संयोजित करना होगा जहां डिबगिंग होनी चाहिए, और कोई अन्य कोड जो उन कंटेनर के साथ इंटरैक्ट करता है। इसका मतलब है कि एक विशेष मानक कंटेनर उदाहरण तक पहुंचने वाली अनुवाद इकाइयों का एक सेट या तो रिलीज मोड (कोई जांच नहीं) या डीबग मोड (पूर्ण जांच) में संकलित किया जा सकता है, लेकिन सभी को उसी तरह संकलित किया जाना चाहिए; एक अनुवाद इकाई जो नहीं देखती है कि मानक कंटेनर उदाहरण को पुन: संकलित करने की आवश्यकता नहीं है। इसका मतलब यह भी है कि एक अनुवाद इकाई ए जिसमें रिहाई मोड में संकलित एक विशेष तत्कालता (कहें, std :: वेक्टर) शामिल है, को एक अनुवाद इकाई बी के साथ जोड़ा जा सकता है जिसमें डीबग मोड में संकलित एक ही तत्कालता होती है (एक सुविधा आंशिक पुनर्मूल्यांकन के साथ मौजूद नहीं है)। हालांकि यह व्यवहार तकनीकी रूप से एक परिभाषा नियम का उल्लंघन है, यह क्षमता अभ्यास में बहुत महत्वपूर्ण है। LibstdC++ डीबग मोड पुन: संकलन के इस स्तर का समर्थन करता है।

प्रति इकाई संकलन है, जो आपको यहाँ करने के लिए कोशिश कर रहे हैं क्या है के

, यह कहते हैं:

हम मानते हैं कि रखता के इस स्तर संभव नहीं वास्तव में अगर हम सुरक्षित आपूर्ति करने का इरादा iterators, कार्यक्रम अर्थ विज्ञान अपरिवर्तित छोड़, और नहीं रिलीज मोड के तहत प्रदर्शन में वापस आना ....

इस प्रकार, अपने पिछले प्रश्न पर मेरा उत्तर पूरी तरह से सही नहीं था, और मैं माफी माँगता हूँ। मैंने इसे ठीक करने के लिए इसमें एक परिशिष्ट जोड़ा है, जो मुझे आशा है कि बहु-लाइब्रेरी समस्या को हल करने के बारे में एक उपयोगी सुझाव है।

12

आपकी समस्या केवल a.cpp करने के लिए -D_GLIBCXX_DEBUG गुजर रहा है। यह ध्वज एसटीएल संरचनाओं को अतिरिक्त डीबगिंग जानकारी जोड़ता है, और इस तरह के उपयोग को आपके प्रोजेक्ट की सभी फाइलों में सुसंगत होना चाहिए। अन्यथा, std::vector और std::string के मेमोरी लेआउट के बारे में अलग-अलग फ़ाइलें असहमत हैं, जिसके परिणामस्वरूप अपरिभाषित व्यवहार (आपके मामले में एक क्रैश) होता है।

+0

यह भी मैं समझता हूं।तो, आप मेरे प्रश्न http://stackoverflow.com/questions/4764048/stl-and-release-debug-library-mess के उत्तरों पर टिप्पणी कैसे करेंगे। क्या मैं जवाबों को गलत नहीं समझता या मेरा प्रश्न स्पष्ट/सही नहीं है? – dimba

+2

स्पष्ट होने के लिए, सामान्य रूप से, झंडे को एक बार और सभी के लिए सेट किया जाना चाहिए और उन फ़ाइलों के पूरे सेट पर लगातार लागू होना चाहिए जिन्हें आप संकलित करना चाहते हैं। –

+0

@Matthieu क्या आप – dimba

संबंधित मुद्दे