名前空間
変種
操作

realloc

From cppreference.com
ヘッダー <stdlib.h> で定義
void *realloc( void *ptr, size_t new_size );

指定されたメモリ領域を再割り当てします。ptr が NULL でない場合、それは以前に malloccalloc、または realloc によって割り当てられ、まだ free または realloc の呼び出しで解放されていない必要があります。それ以外の場合、結果は未定義です。

再割り当ては、次のいずれかの方法で行われます。

a) 可能な場合、ptr が指す既存の領域を拡張または縮小します。領域の内容は、新しいサイズと古いサイズの小さい方まで変更されません。領域が拡張された場合、配列の新しい部分の内容は未定義です。
b) サイズ new_size バイトの新しいメモリブロックを割り当て、新しいサイズと古いサイズの小さい方と同じサイズのメモリ領域をコピーし、古いブロックを解放します。

メモリが不足している場合、古いメモリブロックは解放されず、NULL ポインタが返されます。

ptrNULL の場合、動作は malloc(new_size) を呼び出すのと同じです。

それ以外の場合、

new_size がゼロの場合、動作は実装定義です(NULL ポインタが返される可能性があります(その場合、古いメモリブロックは解放されることもされないこともあります)、またはストレージにアクセスするために使用できない非NULLポインタが返されることもあります)。(C17以降) そのような使用は非推奨です(C DR 400経由)。

(C23まで)

new_size がゼロの場合、動作は未定義です。

(C23以降)

realloc はスレッドセーフです。引数を通して見えるメモリ位置のみにアクセスし、静的ストレージにはアクセスしないかのように動作します。

メモリ領域を解放する free または realloc の以前の呼び出しは、同じまたは同じ領域の一部を割り当てる realloc を含む、すべての割り当て関数の呼び出しと *同期* します。この同期は、解放関数によるメモリへのアクセス後、および realloc によるメモリへのアクセス前に行われます。特定のメモリ領域を操作するすべての割り当ておよび解放関数の単一の全体順序が存在します。

(C11 以降)

目次

[編集] パラメータ

ptr - 再割り当てするメモリ領域へのポインタ
new_size - 配列の新しいサイズ(バイト単位)

[編集] 戻り値

成功した場合、新しく割り当てられたメモリの先頭へのポインタを返します。メモリリークを回避するために、返されたポインタは free または realloc で解放する必要があります。元のポインタ ptr は無効になり、それへのアクセスは未定義の動作となります(インプレース再割り当てが行われた場合でも)。

失敗した場合、NULL ポインタを返します。元のポインタ ptr は有効なままであり、free または realloc で解放する必要がある場合があります。

[編集] 注意

元々(C89)、以下のようなコードをサポートするためにゼロサイズのサポートが追加されました。

OBJ *p = calloc(0, sizeof(OBJ)); // "zero-length" placeholder
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // reallocations until size settles
    /* code that may change c or break out of loop */
}

[編集]

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
 
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
 
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
 
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // finally, frees the storage
    return EXIT_SUCCESS;
}

実行結果の例

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

[編集] 参照

  • C23標準 (ISO/IEC 9899:2024)
  • 7.22.3.5 realloc 関数 (p: TBD)
  • C17標準 (ISO/IEC 9899:2018)
  • 7.22.3.5 realloc 関数 (p: 254)
  • C11標準 (ISO/IEC 9899:2011)
  • 7.22.3.5 realloc 関数 (p: 349)
  • C99標準 (ISO/IEC 9899:1999)
  • 7.20.3.4 realloc 関数 (p: 314)
  • C89/C90標準 (ISO/IEC 9899:1990)
  • 4.10.3.4 realloc 関数

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)