4

私は malloc の実装を書いていて、誰かがこの問題を手伝ってくれるかどうか疑問に思っていました。

基本的にはsbrk()でメモリを確保し、メモリが空いていることを確認してから再利用したい。

つまり、基本的に、私の記憶がこのようになっていると想像してください

|------------------------------|

...そして、いくつかの割り当てを行います。メモリを割り当てると、各ビットにヘッド (h) とデータ (d) があります。

|hddddddhddd---hdd--hddd-------|

これでこれらの穴ができました。たとえば、ダイアグラムの最初のギャップを使用したい場合、ヘッド (h) とボディ (dd) も持つように設定するにはどうすればよいでしょうか?

必要なメモリ位置へのポインタを取得したところまで来ました。C では、ポインターによってポイントされます。ポインターにはカスタム型があり、「メタ」は私が定義した構造体です。だから今私は持っています

metaStruct * mypointer = the memory address.

しかし、私がやろうとすると

mypointer->size = 30;

または

mypointer->buddy = 1;

セグメンテーション違反が発生します。

質問: sbrk() を介して割り当てられたメモリ アドレスが構造体の形式になるように設定するにはどうすればよいですか? 明らかに、私は単に myPointer = malloc(sizeof(metaStruct)) に行くことはできません。なぜなら、私は malloc 自体を書いているからです。sbrk() でより多くのスペースを使用することにも興味がありませんが、私が指摘している既存のスペースを利用することには興味があります (ジャンク データを無視してスペースを使用したい)。

どうすればそれを行うことができますか?

4

1 に答える 1

4

私が知る限り、p=sbrk(n) は (少なくとも) n バイトの使用可能なアドレス空間を拡大し、「p」に新しく割り当てられた領域のベース アドレスを返します。これで、「p」から始まる n バイト長のメモリ ブロックができました (システムによっては、おそらく n よりも大きくなります)。

したがって、「metaStruct」には「サイズ」フィールド、「次の空き領域」フィールド、および「データ」フィールドが含まれていると思います。

metaStruct * m ;
p=sbrk(sizeof(metaStruct)+ data_size);
m = (metaStruct *)p;
m->size = data_size;
m->next = NULL;
memcpy(m->data, ...,data_size);

コードは完全ではありません。一部のシステムでは、sbrk 関数 (実際、多くの場合、基本的なシステム コールではなく関数です。もちろん、sbrk が失敗したかどうかを確認する必要があります) は、整列されたポインターを返さないため、ポインターを手動で整列する必要があります。 . また、sbrk(n) の後に sbrk(0) を呼び出し、2 つのポインターの差を計算することによって、実際に割り当てられたサイズを取得できます。一般に、「空きブロック」のコレクションを維持し、それらを最初に使用してみて、十分な大きさのブロックがない場合にのみ sbrk を呼び出す必要があります。

于 2011-03-26T10:47:17.860 に答える