std :: string :: assign()はセグメンテーション違反を引き起こします
-
07-07-2019 - |
質問
特定のオフセットの文字列を含む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 ................
...
オフセット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が返され、ベクターをループしてデータを印刷しても問題はありません(クラッシュするスニペットのすぐ上に!)。
Debianでg ++ 4.3.4を使用してコンパイルしています。この問題の可能性に関する指針はありますか?
解決
コードのどこか他の場所でフリー/削除の不一致が発生している可能性があり、現在まで症状が遅れています。解放されたメモリを使用する場合、オペレーティングシステムは適切と判断される限り、自由に続行できます。
valgrindでプログラムを実行してみてください。 valgrindは独自のmallocとfreeを使用するため、誤ったニュースや削除を警告できます。必ず最適化せずにコンパイルして、-g
1 :
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 について<=>、マンページから:オペレーティングシステムのネイティブ形式(スタブ、COFF、XCOFF、またはDWARF 2)でデバッグ情報を生成します。 GDBはこのデバッグ情報を使用できます。