0

コア ダンプをデバッグしていますが、std::string のコピーを作成するときにアプリがコア化したようです。文字列の内容が少し壊れているように見えるため、クラッシュはコピー前に文字列が破壊されたか、または他のコードが文字列の一部を上書きしたことが原因です。gdb で、文字列がまだ存在するかどうか (したがって、メモリが上書きされているかどうか)、または文字列がコピー前に破棄されているかどうかを判断することはできますか?

4

1 に答える 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 に答える