2011-06-17 14 views
4

Cでmallocを試していましたが、メモリが割り当てられた後にmallocがいくらかのスペースを無駄にしていることがわかりました。以下は、私は、次の絵の右中央にはmallocCのmallocメモリ割り当て方式

#include <stdlib.h> 
#include <string.h> 

int main(){ 
    char* a; 
    char* b; 
    a=malloc(2*sizeof(char)); 
    b=malloc(2*sizeof(char)); 
    memset(a,9,2); 
    memset(b,9,2); 
    return 0; 
} 

をテストするために使用されるコードの一部を使用すると、メモリの内容を見ることができます(わかりやすくするために新しいタブで画像を開く)であり、0x804b008が指すアドレスです変数 'a'によって表され、0x804b018は変数 'b'によって指し示されるメモリです。 0x804b00aから0x804b017までの間に何が起こっていますか?私が2*sizeof(char)バイトのメモリの代わりに3*sizeof(char)を割り当てようとしても、メモリのレイアウトは同じです!それで、私が紛失しているものがありますか?

gdb interface

+0

以下の答えに加えて、定義によってsizeof(char)= 1ということを指摘しておく価値があるので、それを乗算する点はありません。 –

+0

@richardkettlewellそうですが、私は読みやすさのために何らかの方法でそれを使う習慣を作ったのです – nagavamsikrishna

答えて

8

malloc()それが望んでいるほど多くのスペースを無駄に許可されている - 標準は、実装についてが指定されていません。あなたが持っている唯一の保証は、アライメント(§7.20.3メモリ管理機能)についてです:

割り当てが成功した場合、ポインタが返され、それはオブジェクトの任意の型へのポインタに割り当てることができるように適切に整列されますそのようなオブジェクトまたはそのようなオブジェクトの配列に、割り当てられたスペース内に(スペースが明示的に割り当てが解除されるまで)アクセスするために使用されます。

あなたの実装は、最小8バイトの位置合わせされたポインタを返すようです。

+0

あなたは7.20.3とは何ですか?それはいくつかのCの標準の本の章ですか?もしそうなら、あなたは私にその本を指摘できますか? – nagavamsikrishna

+1

@vamsi、はい、それはCの仕様です。 PDFリンク:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf –

3

メモリアラインメント! x86の性能にはいいですし、ARMのようないくつかのアーキテクチャでは必須です。

ほとんどのCPUでは、オブジェクトや変数がシステムのメモリ内の特定のオフセットに存在する必要があります。たとえば、32ビットプロセッサでは、4で割り切れるメモリアドレスに4バイトの整数が存在する必要があります。この要件を「メモリアライメント」といいます。したがって、メモリアドレス0x2000または0x2004に4バイトのintを配置できますが、0x2001では配置できません。ほとんどのUnixシステムでは、整列していないデータを使用しようとするとバスエラーが発生し、プログラムが完全に終了します。インテル・プロセッサーでは、ミスアライメントされたデータの使用がサポートされていますが、パフォーマンスが大幅に低下します。したがって、ほとんどのコンパイラは、使用されている特定のプロセッサとそのタイプに従ってデータ変数を自動的に整列させます。構造体とクラスが占める大きさは、多くの場合、そのメンバーの

http://www.devx.com/tips/Tip/13265

0

最近のほとんどのmalloc()実装は断片化を減らすために、2の累乗に割り当て、最小割り当てサイズを持っているとの合計よりも大きくなっている理由はここにあります奇数サイズは、一般に、より大きなブロックを作成するのに十分な連続的な割り当てがfree()dである場合にのみ再利用することができるからです。 (また、一般的には、連続した割り振り、IIRCのスピードを上げます。)また、ブロックオーバーヘッドに留意してください。ブロックサイズを取得するには、内部管理用にいくらかの量(GNU malloc()の8、IIRC)を追加する必要があります。

0

mallocは、指定したサイズ以上のメモリブロックを返すことが保証されています。しかし、プロセッサは一般に、メモリのブロック数(例えば、メモリ内の8バイトの倍数で開始する)で動作しているときに、より効率的です。詳細については、ワードサイズを参照してください。

2

ヒープは実装によって処理されますが、必ずしも期待どおりではありません。スタンダードは、秩序または連続性について何ら保証しません。あなたが求めたより多くのヒープスペースを使用させる主なものが2つあります。

最初に、割り当てられたメモリは、どのような種類のオブジェクトでも使用するのに適していなければなりません。通常、NバイトのプリミティブデータオブジェクトはNの倍数で割り当てられるため、malloc()は8の倍数でない値を返すことはできません。

第2に、ヒープfree()がメモリを再利用できるように管理する必要があります。つまり、ヒープマネージャは、割り当てられたブロックと割り当てられていないブロック、およびそのサイズを追跡する必要があります。 1つの方法は、各ブロックの直前にいくつかの情報をメモリに張り付けることで、マネージャはどのサイズのブロックを解放するのか、どのブロックが再利用されるのかを知ることができます。これがあなたのシステムであれば、割り当てられたブロック間でより多くのメモリが使用され、8バイトの位置合わせ制限が与えられれば、16バイト未満の割り当てを得ることはできません。

関連する問題