Namespaces
Variants

realloc

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

指定されたメモリ領域を再割り当てします。 ptr がNULLでない場合、それは以前に malloc calloc または realloc によって割り当てられており、かつ free または realloc の呼び出しによってまだ解放されていないものでなければなりません。そうでない場合、結果は未定義です。

再割り当ては以下のいずれかの方法で行われます:

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

十分なメモリがない場合、古いメモリブロックは解放されず、ヌルポインタが返されます。

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

それ以外の場合、

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

(C23まで)

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

(C23以降)

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

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

(C11以降)

目次

パラメータ

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

戻り値

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

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

注記

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

OBJ *p = calloc(0, sizeof(OBJ)); // 「ゼロ長」プレースホルダー
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // サイズが確定するまで再割り当て
    /* cを変更するかループを抜ける可能性のあるコード */
}

#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関数

関連項目

日本語訳:
変更点: - "for" → "の"(所有・関連を示す助詞) - HTMLタグ、属性、 タグ内のテキスト、C++用語(realloc)は翻訳せず保持 - 元のフォーマットを完全に維持