コア ダンプをデバッグしていますが、std::string のコピーを作成するときにアプリがコア化したようです。文字列の内容が少し壊れているように見えるため、クラッシュはコピー前に文字列が破壊されたか、または他のコードが文字列の一部を上書きしたことが原因です。gdb で、文字列がまだ存在するかどうか (したがって、メモリが上書きされているかどうか)、または文字列がコピー前に破棄されているかどうかを判断することはできますか?
1 に答える
2
gcc と gcc から std::string を使用する場合 (たとえば、STLport からではなく)、 std::string 内に内部構造があり、_M_refcount を保持します。これは、破壊後にゼロ以下になります (ロシア語でいくつかの図を含む詳細な説明があります)。"Несколько подробностей об std::string" :
これは、gcc 4.3.3 の basic_string.h からのものです。
void
_M_dispose(const _Alloc& __a)
{
#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
-1) <= 0)
_M_destroy(__a);
} // XXX MT
~basic_string()
{ _M_rep()->_M_dispose(this->get_allocator()); }
したがって、これは簡単なテストです。
#include <string>
#include <stdio.h>
int main()
{
{
std::string s1("ABCDEFGHIJKLMNOPRSTUF1234567890");
printf("Before destruction\n");
}
return 0;
}
コンパイルおよびビルド:
g++ -m64 -g -pthread main.cpp
そして、これはgdbの下にあります:
>gdb -q ./a.out
(gdb) start
Temporary breakpoint 1 at 0x400787: file main.cpp, line 7.
[Thread debugging using libthread_db enabled]
Temporary breakpoint 1, main () at main.cpp:7
7 std::string s1("ABCDEFGHIJKLMNOPRSTUF1234567890");
(gdb) n
8 printf("Before destruction\n");
(gdb) x/4gx (((void**)&s1)[0]-24)
0x601010: 0x000000000000001f 0x000000000000001f
0x601020: 0x0000000000000000 0x4847464544434241
(gdb) x/32c (((void**)&s1)[0])
0x601028: 65 'A' 66 'B' 67 'C' 68 'D' 69 'E' 70 'F' 71 'G' 72 'H'
0x601030: 73 'I' 74 'J' 75 'K' 76 'L' 77 'M' 78 'N' 79 'O' 80 'P'
0x601038: 82 'R' 83 'S' 84 'T' 85 'U' 70 'F' 49 '1' 50 '2' 51 '3'
0x601040: 52 '4' 53 '5' 54 '6' 55 '7' 56 '8' 57 '9' 48 '0' 0 '\000'
(gdb) n
Before destruction
10 return 0;
(gdb) x/4gx (((void**)&s1)[0]-24)
0x601010: 0x0000000000000000 0x000000000000001f
0x601020: 0x00000000ffffffff 0x4847464544434241
(gdb) x/32c (((void**)&s1)[0])
0x601028: 65 'A' 66 'B' 67 'C' 68 'D' 69 'E' 70 'F' 71 'G' 72 'H'
0x601030: 73 'I' 74 'J' 75 'K' 76 'L' 77 'M' 78 'N' 79 'O' 80 'P'
0x601038: 82 'R' 83 'S' 84 'T' 85 'U' 70 'F' 49 '1' 50 '2' 51 '3'
0x601040: 52 '4' 53 '5' 54 '6' 55 '7' 56 '8' 57 '9' 48 '0' 0 '\000'
破壊後にわかるように、0x601020 の値は 0x00000000ffffffff になります。_M_refcount は 4 バイトの長さなので、破棄後は ffffffff (-1) になります。
于 2013-10-03T12:50:40.307 に答える