私は現在、Android デバイス用の C++ で共有ライブラリを開発しています。
テストを書いているときに、コード例で関数を呼び出すと、segfault (dlfree) を引き起こす奇妙な動作に出くわしました。
初めに:
- ライブラリ関数を呼び出すテストは、ライブラリに対して動的にリンクします。
- Linux および Windows デスクトップ用のライブラリとテストもコンパイルしました。そこでは、セグメンテーション違反を引き起こすことなく実行されます。
- 静的にリンクすると、segfault は android に表示されません。
サンプルコード
typedef unsigned int DBRuleID;
typedef std::string DBRuleTarget;
struct DBRule {
DBRuleID id; //int
DBRuleTarget target; //std::string
};
//segfault variant
bool getRule(DBRuleID id, DBRule& rule) {
rule.target = "I am causing segfault!";
return true;
}
//working variant
bool getRule(DBRuleID id, DBRule& rule) {
//nothing is set
return true;
}
セグメンテーション違反
Build fingerprint: 'generic/sdk/generic:3.0/HONEYCOMB/104254:eng/test-keys'
pid: 525, tid: 525 >>> /data/local/TestRulesDB <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
r0 deadbaad r1 0000000c r2 00000027 r3 00000000
r4 00000080 r5 aff46658 r6 00013000 r7 00000004
r8 00000004 r9 00013d3c 10 00000000 fp bec61a14
ip ffffffff sp bec61950 lr aff193e9 pc aff15f58 cpsr 00000030
#00 pc 00015f58 /system/lib/libc.so
#01 pc 00012d2a /system/lib/libc.so (dlfree)
編集 - 新しい調査結果
関数に渡される DBRule 構造体が値で初期化されている場合、すべて正常に動作しますが、それ以外の場合はセグメンテーション違反が発生します。
//works
DBRule rule_1 = { 0, "target"};
//works not
DBRule rule_1 = { 0, ""};
//works not
DBRule rule_1;
誰かが私にそれを説明してもらえますか? そして、デフォルトで初期化する最良の方法は何ですか?
質問は
- 私は何を間違っていますか、何が欠けていますか?
- ヒープに割り当てられたメモリを複数回削除しようとするメカニズムはありますか?
デスクトップで valgrind を起動しましたが、エラーは表示されません。
前もって感謝します!