はI」のインタフェースクラスC++クラスライブラリ動的ランタイム割り当て
class foo_if_t {
};
、foo_if_t
から継承し、次のコードを持つクラスfoo_t
と最初のライブラリlibfoo_orig.so
を有していると仮定します第2ライブラリlibfoo_mod.so
クラスfoo_t
は次のように再定義されます。
#include "foo_if.h"
class foo_t : public foo_if_t{
private:
int res[100];
public:
foo_t() {
for (int i=0; i<100; i++)
res[i] = i;
}
virtual ~foo_t(){}
};
私はシンボリックリンクlibfoo.so --> libfoo_orig.so
を作成し(したがってにlibfoo.soにリンク)g++ -ggdb -O0 test.cpp -o test -L. -lfoo
で次のアプリケーション
#include "foo_orig.h"
int main(){
foo_if_t *foo_if = new foo_t();
delete foo_if;
}
をコンパイル。
この時点で私はシンボリックリンクをlibfoo_mod.so
に変更し、コードを再実行します。これは、次のエラーになります:
*** Error in `./test': free(): invalid next size (fast): 0x0000000001ec9010 ***
Aborted (core dumped)
私はそれが起こってできたと考えていることはfoo_mod.so
foo_t
コンストラクタである場合は、ライブラリfoo_orig.so
からfoo_t
のコンストラクタの割り当てはそう、foo_mod.so
から1以上のヒープの小さな塊を食べることです呼び出されると、割り当て境界を越えてヒープメモリがダーティになります(したがって、ヒープを破損しますnext
チャンク参照)。これは、実際にコンストラクタコードが呼び出されたことに基づいて、実行時に動的に解決されると考えていたのに対し、ヒープの予約はリンク時に何らかの形で事前計算されていると私に伝えています。私は間違っていますか?もしそうでなければ、生成された出力コードはなぜこのように動作していますか?
耐性テストとして、私はstatic foo_it_t * foo_if_t::new_instance()
の実装内でnew foo_t()
呼び出しを各ライブラリに書きました。メインコードからnew_instance
を呼び出すと正しく動作します。