0

大学で独自のバージョンの malloc() を実装したとき、2 つのリンク リストを使用しました。フリー リストと割り当て済みバッファ リストです (不足したときに sbrk の呼び出しが散在しています)。しかし今、私は現実世界の問題を抱えています: 私たちのソフトウェア malloc のバッファはリンクされたリストに置かれ、数時間後に何らかの関数のコードによって解放される可能性があります。しかし、malloc() と同じ関数に free() を持つコードはほとんどありません。

これにより、malloc されたバッファが 2 回解放されることがあります。Solaris では、アプリが長時間実行されているため、これは明らかに問題ではありませんでした。しかし、Linux (RH) でコードを実行すると、このバグが突然発生しました。

malloc() の内部動作はわかりませんが、明らかに実装依存です。Linux/gcc の実装が、割り当てられたバッファーのリストを保持しているかどうかはわかりません。(フリーリストは必須です。割り当てられたリストは?それほど多くはないと思います。)これが私の質問のポイントにつながります。

  1. この malloc の実装は、割り当てられたメモリ領域のリストを使用しますか?
  2. そのリストをスキャンして特定のポインターを見つける関数はありますか (非公式でも問題ありません)。

ant2009 による質問に対する私の hmjd の回答を読んだ後、私のスキームは、上記の回答が「はい」の場合、free() への呼び出しを展開されたコードのマクロに置き換えることです。

  • ポインターが null かどうかを確認します。その場合、次のいくつかのステップをスキップします
  • この不思議な関数を呼び出して、まだ malloc されていることを確認します
  • Frees は free() を使用した本によるものです
  • ポインターが既に解放されていることを示すシグナルとして、ポインターを null にします。もう解放しないでください。

このような機能は確かにこのマニュアル ページにはありませんが、私は歓迎します。(私がこれを書いているとき、私は glibc-2.17.tar.xz をダウンロードしようとしています。そこにも私の答えがあります。)

ありがとう。(ここまで読むだけでも!)

-- ジェイコブ

4

1 に答える 1

1

あなたのクラッシュではなく、ここに大きな問題があります...

アドレスに基づいて、2番目の空きがあなたのオブジェクトを対象としているか、それともその間にmallocされて使用されている別のオブジェクトを対象としているかを判断することはできません...

あなたのポイントについて:

  • ポインターが null かどうかを確認します。その場合、次のいくつかをスキップします
    • free()最新のすべての実装でヌルセーフです。問題はありません。
  • ステップまだmallocされていることを保証するために、この不思議な関数を呼び出します
    • それが意図したオブジェクトであるかどうかはまだわかりません。
  • Frees は、free() を使用して本によるものです
    • これが何を意味するのかわかりません
  • すでに解放されています。もう解放しないでください。
    • これが問題の核心です。ここに来ると、あなたは悪い状態になります。

バグがあり、C 言語を修正したいという衝動と戦ってコードを修正する必要があります...

NULLポインターを 'ing することは良いことですが、ポインターのコピーをいったん手渡すと、ローカル コピーを null にしても、他のコピーは null にならないという点で、これは 1 つのステップにすぎません。

これが確実に必要な場所である場合は、別のレベルの無関心を使用できます。

void ** handle;
void ** handle2;

void * obj = malloc(5);

handle = &obj;
handle2 = &obj;

free(*handle);
*handle = NULL;

free(*handle2);
*handle2 = NULL;

その後、ヌル化objが役立つ可能性があります...

于 2013-05-10T19:39:58.813 に答える