reallocの書き方を考えましたが、コードが正しくないことは知っていますか?
質問
私がやろうと決めたのは
- mallocを呼び出す
- 古いブロックを新しいブロックにコピーする
- 古いブロックを解放する
- 新しいブロックへのポインタを返します
以下のコードは私がこれまでに持っているものです...しかし、私はそれが正しくないことを知っています...コードを修正するのにどんな助けでも大歓迎です...
私が提供したものよりも多くのコードが必要な場合は、このコードの前にすべてのコードを示す投稿があります。私は新しいので、この投稿と最後に行った投稿のみがあります。 ありがとう。
void *mm_realloc(void *ptr, size_t size)
{
int i, p = *ptr;
// make a call to malloc to find space
//allocate memory
ptr = malloc(size_t*sizeof(int));
//copying old block to new block
if(ptr!=NULL)
for(i=0 ; i<size_t ; i++)
{
*(ptr+i) = i;
}
//freeing old block
free(ptr);
//return pointer to new block
return *ptr;
}
解決
理想的には、 realloc()
は現在のブロックを超える十分な空きメモリがあるかどうかを単純に確認し、もしそうであれば、アリーナデータ構造を調整して現在のブロックをインプレース展開します。これにより、コストのかかるコピー操作がなくなり、割り当てが失敗する可能性が低くなります。サイズを大きくするためです。削減するには、現在のブロックの残りを空きプールに送り返し、常にインプレースで実行できる必要があります。
malloc / freeを実行することにより、単一の60Kブロックが割り当てられたアリーナに100Kがある場合、 mm_realloc
を呼び出してサイズを50Kに調整すると失敗します。
ただし、少なくとも最初の試みでは実行可能なソリューションであるため、次のように実装します。
void *mm_realloc (void *ptr, size_t size) {
int minsize;
void *newptr;
// Allocate new block, returning NULL if not possible.
newptr = malloc (size);
if (newptr == NULL) return NULL;
// Don't copy/free original block if it was NULL.
if (ptr != NULL) {
// Get size to copy - mm_getsize must give you the size of the current block.
// But, if new size is smaller, only copy that much. Many implementations
// actually reserve the 16 bytes in front of the memory to store this info, e.g.,
// +--------+--------------------------------+
// | Header | Your data |
// +--------+--------------------------------+
// ^
// +--- this is your pointer.
// <- This is the memory actually allocated ->
minsize = mm_getsize (ptr);
if (size < minsize)
minsize = size;
// Copy the memory, free the old block and return the new block.
memcpy (newptr, ptr, minsize);
free (ptr)
}
return newptr;
}
お気づきのことの1つは、古いブロックと新しいブロックの最小に十分なバイトだけをコピーする必要があることです。そうしないと、コアダンプの1つがオーバーフローしてコアダンプが発生する危険があります。
さらに、ループは実際にデータをコピーせず、ブロックの各バイトをオフセットに設定し、新しいポインターを割り当てるときに古いポインターを失ったため、 newptr
別々に保つため。
他のヒント
古いブロックと新しいサイズの大きさを知る必要があります。新しいブロックに2つのサイズのうち小さい方をコピーする必要があります。
また、malloc()が失敗した場合に古いブロックを破棄(解放)しないようにする必要があります-0を返すだけです。
また、malloc()でサイズに 'sizeof(int)'を掛ける必要もありません。あなたは本当に4倍以上で全体を割り当てています(理論上は2倍にすぎないかもしれませんが、最近では16ビットコンパイラを使用する人はほとんどいません)。
realloc
のポイントは、可能であれば、メモリブロックをその背後の空きブロックにマージしようとすることです。空きブロックがない場合のみ、新しいメモリを割り当て、すべてをコピーし、古いブロックを解放します。
とにかく独自の割り当てルーチンを書いているのはなぜですか?