2009-09-14 298 views
6

我有一個std::vector<uint8_t>包含特定偏移字符串。這裏有一個縮短轉儲:std :: string :: assign()導致段錯誤

... 
@128 00 00 00 00 00 00 00 00 73 6F 6D 65 74 68 69 33 ........somethin 
@144 38 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ng.............. 
@160 00 00 00 00 00 00 00 00 31 2E 32 2E 33 00 00 00 ........1.2.3... 
@176 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 
... 

我試圖提取數據偏移量136,並把它變成一個std::string

std::string x; 
x.assign(vec.begin()+136, vec.begin()+168); 

然而,這會導致我的應用程序段錯誤。現在我在Linux下的軟件開發相當新的,但我不知道如何開始我的應用程序在GDB,並得到一個回溯,並跟蹤到這裏的問題:

(gdb) backtrace 
#0 0xb7536d78 in ??() from /lib/i686/cmov/libc.so.6 
#1 0xb7538cd5 in malloc() from /lib/i686/cmov/libc.so.6 
#2 0xb7708957 in operator new(unsigned int)() from /usr/lib/libstdc++.so.6 
#3 0xb76e4146 in std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&)() from /usr/lib/libstdc++.so.6 
#4 0xb76e63b0 in std::string::_M_mutate(unsigned int, unsigned int, unsigned int)() from /usr/lib/libstdc++.so.6 
#5 0xb76e654a in std::string::_M_replace_safe(unsigned int, unsigned int, char const*, unsigned int)() from /usr/lib/libstdc++.so.6 
#6 0x0806d651 in std::string::_M_replace_dispatch<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0xbfffe464, __i1=..., __i2=..., __k1=..., __k2=...) at /usr/include/c++/4.3/bits/basic_string.tcc:637 
#7 0x0806d26e in std::string::replace<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:1390 
#8 std::string::assign<__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char> > > > (
    this=0x811c730, vec=...) at /usr/include/c++/4.3/bits/basic_string.h:958 
#9 myclass::somemethod (this=0x811c730, vec=...) at myclass.cpp:135 

印刷vec.size()返回200,甚至遍歷向量和打印數據導致我沒有任何問題(正好在崩潰的片段之上!)。

我使用g ++ 4.3.4編譯Debian。任何關於這個問題可能的指針?

回答

13

您的代碼中可能存在不匹配的空閒/刪除,導致症狀延遲到現在。當您使用釋放的內存時,操作系統可以自由地繼續,只要它看起來合適。

嘗試在valgrind中運行該程序。 valgrind使用它自己的malloc並且是免費的,所以它可以提醒你不正確的消息和刪除。確保compile without optimisations-g

g++ -g main.cc -o binary 
valgrind --leak-check=full ./binary 

確保你沒有創建從超出範圍堆棧變量的指針。例如,這是新開發的通病:

int *foo() { 
    int a = 0; 
    // do something to a here 
    return &a; 
} 

其已經超出了範圍,你是返回一個指針來釋放內存。


關於-g,從手冊頁:產生的操作系統的本機格式(刺,COFF,XCOFF,或DWARF 2)的調試信息。 GDB可以使用這個調試信息。

+0

由於內存已經在一個向量中,我懷疑問題在於新/刪除不匹配。 – 2009-09-14 00:32:31

+0

有趣的是,如果我通過valgrind運行它,不會發生段錯誤... – 2009-09-14 00:33:10

+0

不要深入到具體細節,我試圖刪除不存在的addrinfo結構。我打電話給freeaddrinfo()但沒有將指針設置爲NULL,這導致我嘗試再次刪除相同的內存。 – 2009-09-14 00:55:01