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 呼び出しでこの操作と同様のことを許可しているようです。それで、私は興味があります.bootmemアロケーターがこれを許可するのに、ANSI Cは許可しないのはなぜですか?

4

3 に答える 3

3

いいえ、メモリの部分的な解放を可能にする関数はありません。
ただし、realloc()を使用してメモリのサイズを変更できます。

c標準から:

7.22.3.5realloc関数

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

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

于 2012-03-01T07:48:40.033 に答える
1

まず、そのようなことが必要になる可能性が高い状況は考えられません(回答に記載されているように、メモリを増減するためにreallocが存在する場合)。

もう一つ付け加えたいことがあります。私が見た malloc サブシステムの実装 (それほど多くはないことは認めます) では、malloc と free はプレフィックス バイトと呼ばれるものに依存するように実装されています。したがって、malloc によって返されるアドレスが何であれ、内部的に malloc サブシステムは、アドレスが返される前に追加のメモリ バイトを割り当て、割り当てられたバイト数と使用する割り当てポリシーを含むサニティ チェック情報を保存します。 (OS が複数のメモリ割り当てポリシーをサポートしている場合) など。free (x バイト) のようなことを言うと、malloc サブシステムはプレフィックス バイトを再度確認してサニティ チェックを行い、プレフィックスが所定の位置にあることがわかった場合にのみ解放を行います。正常に発生します。したがって、その間に始まるいくつかのブロックを解放することはできません。

于 2012-03-01T10:20:15.373 に答える
1

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

ここで、メモリを割り当てた場合:

char * tmp = malloc(2048); 

最初の 1 K のメモリの割り当てを解除する場合は、次のようにします。

tmp = realloc(foo, 2048-1024);

ただし、この場合の問題は、が変更されないままであると確信できないことです。tmpそのため、関数は 2K メモリ全体の割り当てを解除し、別の場所に移動する可能性があります。

reallocの正確な実装についてはわかりませんが、私が理解していることから、コードは次のとおりです。

myptr = malloc( x - y );

実際にmallocは size の新しいメモリ バッファを作成しx-y、次に使用に適合するバイトをコピーmemcpyし、最後freeに元の割り当てられたメモリを s にコピーします。

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

于 2012-03-01T08:17:06.847 に答える