1

私はsbrkを使用してかなり基本的なメモリアロケータを作成しました。私はメモリのチャンク、たとえば65kを要求し、動的メモリを要求する変数の必要に応じてそれを切り分けます。65kブロックに追加してメモリを解放します。65kブロックは、ユニオンsizeof(16バイト)から派生します。次に、ブロックを16バイトの境界に沿って整列させます。しかし、私は異常な行動をとっています。

データ構造を割り当ててデータ構造にデータを入力し始めると、メモリへのアクセスは正常に表示されます。関数呼び出しの1つで、グローバル構造のメンバー変数へのポインターを渡しますが、ポインター引数のアドレスは直接マップされません。そのメンバーのアドレス。

たとえば、この特定のメンバーの実際のアドレスはたまたま0x100313d50ですが、特定の機能(特別なことは何もありません)を実行すると、メンバーのアドレスは0x100313d70として表されます。デバッガー内で実際のアドレスを照会できますが、これが現れる関数内では正しく表示されます。これも最初にアクセスされるメンバーではなく、3番目であるため、2回前のメモリアクセスで問題ありませんが、3回目のアクセス中に、この異常なシフトが見られます。

ずれたブロックを介してこのメ​​モリにアクセスしている可能性はありますか?可能ですが、SIGBUS例外がスローされることを期待しています(SPARCチップ)。-memalign = 16sを使用してコンパイルしているので、ミスアライメントをトラップして修正するのではなく、SIGBUSを使用する必要があります。

私のすべての構造体は16バイトの倍数で埋められています:sizeof(structure)%16 =0。このタイプの動作を経験した人はいますか?一般的に言って、どんな種類のもの/もの/など。ポインタがメモリアドレスを誤って表現する可能性がありますか?

乾杯、トレーシー。

Solaris 10、SunStudio-12、最新のSPARCプロセッサ上のC言語(これが役立つ場合)。

4

1 に答える 1

3

他の誰かが同様の問題を抱えている場合は、自分の質問に答える必要があると思います。

メモリアドレスがシフトした理由は、ユーティリティ関数への以前の呼び出しが誤ってグローバル構造のメタアドレスを上書きし、そのブロックのメタアドレスを書き換えたため、実際のデータがまだ存在していても、そのブロックのルックアップがシフトされたためです。元のブロックで。

簡単に言えば、私は自分のバッファを超えて書きました。私は尻尾からメモリを配っているので、上書きすると、グローバル構造(またはその他)に必要なメタアドレスが吹き飛ばされてしまいます。これで、未定義の動作がどのようになるかがわかりました。

于 2009-09-23T23:18:51.680 に答える