7

std::vector<uint8_t>特定のオフセットに文字列を含むがあります。短縮されたダンプは次のとおりです。

...
@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 ................
...

std::stringオフセット136でデータを抽出し、それを:に入れようとしています。

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でコンパイルしています。この問題が何である可能性があるかについてのポインタはありますか?

4

1 に答える 1

14

今まで症状を遅らせているコードのどこかに不一致の free/delete がある可能性があります。解放されたメモリを使用すると、オペレーティング システムは、適切であると判断する限り、自由に続行できます。

valgrind でプログラムを実行してみてください。valgrind は独自の malloc と free を使用するため、誤ったニュースや削除を警告することができます。最適化なしで1でコンパイルしてください:-g

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

スコープ外のスタック変数からポインターを作成しないように注意してください。たとえば、これは新しい開発者の間でよくある間違いです。

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

a がスコープ外になったため、解放されたメモリへのポインターを返しています。


1について-g、マンページから:オペレーティング システムのネイティブ形式 (stabs、COFF、XCOFF、または DWARF 2) でデバッグ情報を生成します。GDB は、このデバッグ情報を処理できます。

于 2009-09-14T00:20:14.690 に答える