2012-03-01 2 views
1

プログラマが割り当てられたブロックの一部を解放できるようにする動的メモリ割り当てシステムが存在するかどうか不思議でした。例えば動的に割り当てられたブロックの一部を解放しますか?

:これは難しい/愚か/賢明である理由について

char* a = malloc (40); 
//b points to the split second half of the block, or to NULL if it's beyond the end 
//a points to a area of 10 bytes 
b = partial_free (a+10, /*size*/ 10) 

思考?これを行う方法は?

私はそれが役に立ちそうなようです。

ありがとうございます!

=====一部の研究の末、 の後に、Linuxカーネルのbootmemアロケータがbootmem_free呼び出しでこの操作に類似しているようです。ですから、私は興味があります。なぜブートメムアロケータがこれを許可するのですが、ANSI Cはできませんか?

+1

本質的にあなたがやりたいことをする 'realloc'があります。 – Alexander

答えて

3

いいえ胸骨のメモリーを解放する機能はありません。
しかし、realloc()を使用してメモリのサイズを変更できます。

Cの標準から:

7.22.3.5

#include <stdlib.h> 
void *realloc(void *ptr, size_t size); 

realloc関数はrealloc関数は古いオブジェクトがptrが割り当て解除し、その新しいオブジェクトへのポインタを返しますサイズで指定されたサイズを持ちます。新しいオブジェクトの内容は、解放前の古いオブジェクトの内容と同じでなければならず、新しいサイズと古いサイズのうちの小さいものになります。新しいオブジェクト内の古いオブジェクトのサイズを超えるバイトは、不確定な値を持ちます。

+0

しかし、 'realloc'は部分的に解放された部分のメモリ内容を維持しながら、ブロックの途中でメモリを解放することはできません。 – bcr

+0

@bcr:いいえ、そうでないので、答え、**いいえ**。 –

+0

これをダウンボートする理由を知っていますか? –

1

これのための既製の機能はありませんが、これを行うことは不可能ではありません。まず、realloc()があります。 reallocはメモリブロックへのポインタをとり、はサイズを指定してのサイズを変更します。あなたには、いくつかのメモリ割り当てられている場合

は今、:

char * tmp = malloc(2048); 

を、あなたは1メモリのKは、あなたが行うことDEALLOCATEまず、するつもり:

tmp = realloc(foo, 2048-1024); 

しかし、問題この場合は、特定のであることができないということです。tmpは変更されません。以来、関数は、2Kのメモリ全体の割り当てを解除し、別の場所に移動することがあります。

は今、私はのreallocの正確な実装についてはよく分からないんだけど、私が理解から、コード:

myptr = malloc(x - y); 

実際のサイズx-ymalloc SA新しいメモリバッファ、それコピーmemcpyを使用してフィットし、最後にfreeを使用してフィットしたバイトは、元の割り当てられたメモリです。

これは、潜在的な問題を引き起こす可能性があります。たとえば、新しい再割り当てされたメモリは別のアドレスに配置される可能性があるため、過去のポインタは無効になる可能性があります。定義されていないランタイムエラー、セグメンテーションフォールト、一般的なデバッグ地獄が発生します。だから、私はこれに頼らないようにしようとします。

1

まず、このようなことが起こりそうな状況は考えられません(回答に記されているようにメモリを増減するためのreallocがある場合)。

別のものを追加したいと思います。私がmallocサブシステム(これはあまり認められません)を見た実装では、mallocとfreeはプレフィックスバイトと呼ばれるものに依存するように実装されています。したがって、mallocによって返されるアドレスは、内部的にはmallocサブシステムがアドレスを返す前にメモリのいくつかの追加バイトを割り当て、割り当てられたバイト数と使用可能な割り当てポリシーを含むサニティチェック情報を格納します(あなたのOSが複数のmem割り当てポリシーをサポートしている場合など)。フリー(xバイト)のようなものを言うと、mallocサブシステムはプレフィックスバイトをサニティチェックに戻してプレフィックスが見つかるとうまくいく。したがって、間にいくつかのブロックを解放することはできません。

関連する問題