4

次のようにメモリを動的に割り当てています。

char* heap_start1 = (char*) malloc(1);
char* heap_start2 = (char*) malloc(1);

次のようにprintfを実行すると、驚くべきことにアドレスが連続していません。

printf("%p, %p \n",heap_start1,heap_start2);

結果:

   0x8246008, 0x8246018

ご覧のとおり、15 バイトの余分なメモリがデフラグされたままになっています。それは間違いなく単語の配置のせいではありません。この独特の配置の背後にあるアイデアはありますか?

前もって感謝します!

問題があれば、Linuxでgccを使用しています。

4

4 に答える 4

7

glibcmallocは、16バイト未満の小さなメモリ割り当ての場合、単にメモリを16バイトとして割り当てます。これは、このメモリを解放する際の外部フラグメンテーションを防ぐためです。この場合、解放されたメモリのブロックは小さすぎて、一般的なケースでは新しいmalloc操作を実行できません。

によって割り当てられたブロックmallocは、空きブロックを格納するデータ構造で追跡するために必要なデータを格納するのに十分な大きさである必要もあります。

この動作は、内部の断片化を増加させる一方で、システム全体の全体的な断片化を減少させます。

出典: http://repo.or.cz/w/glibc.git/blob/HEAD: /malloc/malloc.c (特に108行目を読む)

/*
...
Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
...
*/

mallocさらに、 glibcでの呼び出しによって返されるすべてのアドレスは、2 * sizeof(size_t)バイトに揃えられます。これは、32ビットシステム(自分のシステムなど)の場合は64ビット、64ビットシステムの場合は128ビットです。

于 2013-01-31T00:16:34.713 に答える
4

少なくとも3つの考えられる理由:

  • mallocすべてのプリミティブ型に適切に配置されたメモリを生成する必要があります。 SSE命令のデータは、128ビットで整列する必要があります。(プラットフォームがサポートしている他の128ビットプリミティブタイプもありますが、現時点では発生しません。)

  • の典型的な実装にmallocは、迅速な簿記情報を保存するための「過剰割り当て」が含まれfreeます。Linux上のGCCがこれを行うかどうかはわかりません。

  • バッファオーバーフローなどを検出できるようにするために、ガードバイトを割り当てている可能性があります。

于 2013-01-31T00:02:36.727 に答える
0

malloc返されたメモリが基本型に対して適切に配置されることを保証します。さらに、設定によっては、メモリ破損をチェックするために、メモリ ブロックにいくつかのガード バイトを埋め込むことができます。

于 2013-01-31T00:13:49.487 に答える
0

連続したアドレスを割り当てたい場合は、同じ malloc に割り当てる必要があります

char *heap_start1, *heap_start2;
heap_start1 = (char*) malloc(2 * sizeof(char));
heap_start2 = heap_start1 + 1;
于 2013-01-31T00:04:54.590 に答える