0

3x3 行列の固有ベクトルを見つけるための数値レシピの標準ルーチンを使用するコードがあります。コードは Linux マシンでは完全に実行されますが、Mac ではセグメンテーション エラー 11 で失敗します。gdbを使用して、追跡したところ、

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000140400008
0x0000000100002a88 in tqli (d=0x7fff5fbffaa4, e=0x7fff5fbffa98, n=3, z=0x140400000) at     ac_nr.c:402
402                         f=z[k][i+1];

ここで、tqli は数値レシピの標準ルーチンであり、z は適切に定義されています。これは自信を持って言えます。なぜなら、Linux マシンではプログラムの実行に問題がなく、正しい答えが得られるからです。Google 検索では、関連する回答が得られません。Macで何が起こっているのか、またはこれを修正する方法を誰かが示唆できますか?

どうもありがとう、

4

2 に答える 2

3
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000140400008
0x0000000100002a88 in tqli (d=0x7fff5fbffaa4, e=0x7fff5fbffa98, n=3, z=0x140400000)
at     ac_nr.c:402
402                         f=z[k][i+1];

ご覧のとおり、zポインタは 0x140400000 で、エラーは 8 バイト後の 0x0000000140400008 で発生します。zこれはおそらく、 (配列が範囲外)に対するバッファ オーバーフローです。

Linux で機能する理由: これは割り当て戦略に関係している可能性があります。たとえば、alloc ライブラリがパフォーマンスを向上させるために 16 バイトのブロックでメモリを割り当て、8 バイトのブロックを要求すると、16 バイトが割り当てられます。プロテクタやカナリアがなければ、境界を越えて 1 つのアイテムに対処することを妨げるものは何もありません。また、1 つの余分なアイテムに相当するものを割り当てれば、セグメンテーション違反は発生しません。

しかし、8 バイトのブロックを割り当てるマシンでは、同じコードがクラッシュします。

Andreas Florath の提案を強く支持します。Linux でプログラムに対して valgrind を実行し、境界外アクセスをチェックします。zまたは、実際にアクセスする場所とサイズを確認することもできます。

于 2012-12-23T11:40:28.220 に答える
0

私はあなたzが正しく定義されていないことをかなり確信しています(またはいくつかの呼び出しconventon設定または同様のものが間違っています)。

コードはLinuxでは「機能する」がMacでは機能しない可能性があります-おそらくメモリ領域の配置が異なるためですが、問題はtqli()に渡すものにあるとほぼ確信しています- d&e値は、saenアドレス(スタック変数の場合)のように見えます。z値は完全に異なる範囲であり、間違っているアドレスはその直後なので、おそらく最初に読み取られます[デバッガーで変数をチェックするiと、間違いなくゼロになります]。k

于 2012-12-23T11:36:57.677 に答える