realloc | Programming Place Plus C言語編 標準ライブラリのリファレンス

トップページC言語編標準ライブラリのリファレンス(名前順)

トップページC言語編標準ライブラリのリファレンス(ヘッダ別)


realloc関数

概要

メモリ領域を確保し直す

ヘッダ

stdlib.h

形式

void* realloc(void* ptr, size_t size);

引数

ptr

動的に確保済みの領域を指すポインタ。あるいは、ヌルポインタ。

size

新しく確保する領域の大きさ。

戻り値

再確保された領域の先頭を指すポインタ。ただし、このポインタは以前確保されていてメモリ領域と同じメモリアドレスを持つ可能性はある。
メモリ不足などの要因で失敗した場合には、ヌルポインタが返される。

詳細

malloc関数calloc関数、realloc関数のいずれかで確保された領域を指定し、再度確保直す。元の領域にあった内容は、新しい領域にコピーされ、元の領域は解放される。

引数ptr がヌルポインタの場合は、malloc関数と同じ動作になる。

引数size が 0 の場合の動作は処理系定義であり、戻り値としてはヌルポインタか、何らかのヌルでないポインタが返される。ヌルでないポインタが返されたとしても、そのポインタを使ったアクセスを行ってはならない1

確保された領域が不要になったら、free関数で解放(システムへ返却)できる。

C95以前の規格では、引数size に 0 を指定した場合には、free関数と同じ動作になった。2

注意

システムがメモリ領域を管理するための追加の領域が必要なため、実際に割り当てられる大きさは、size を超える可能性がある。

引数ptr がヌルポインタでないとき、そのポインタが malloc関数calloc関数、realloc関数によって返されたポインタ(かつ、解放されていない)でない場合の動作は未定義である。

新しい領域の確保に失敗したときにはヌルポインタが返されるが、この場合、元の領域は解放されることなく残されている。そのため、ptr = realloc(ptr, 1000); のように、第1引数に渡すポインタ変数を使って、戻り値を受け取ってしまうと、元の領域に対して free関数の呼び出しを行う手段が無くなってしまう可能性がある。この後の「使用例」で示すように、いったん、別の変数に受け取るべきだろう。

使用例

#include <stdio.h>
#include <stdlib.h>

#define ALLOCATE_SIZE_1ST   (5)
#define ALLOCATE_SIZE_2ND   (10)

int main(void)
{
    int* values = malloc(sizeof(int) * ALLOCATE_SIZE_1ST);
    if (values == NULL) {
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < ALLOCATE_SIZE_1ST; ++i) {
        values[i] = i;
    }

    // 再確保
    int* tmp = realloc(values, sizeof(int) * ALLOCATE_SIZE_2ND);  // いったん、別の変数に受け取る
    if (tmp == NULL) {
        // realloc関数が失敗した場合、元の領域は解放されずに残されている
        // 自分で free関数を呼び出して終了する
        free(values);
        exit(EXIT_FAILURE);
    }
    values = tmp; // 成功したら、受け取ったメモリアドレスをコピー
    tmp = NULL;   // 安全策。確保された領域を指すポインタを array だけに限定する

    for (int i = ALLOCATE_SIZE_1ST; i < ALLOCATE_SIZE_2ND; ++i) {
        values[i] = i;
    }

    for (int i = 0; i < ALLOCATE_SIZE_2ND; ++i) {
        printf("%d\n", values[i]);
    }

    free(values);
}

実行結果:

0
1
2
3
4
5
6
7
8
9

関連

メモリの動的な確保に関わる標準ライブラリ関数として、他に malloc関数calloc関数がある。いずれにしても、解放は free関数で行う。

解説章

第35章


参考リンク


更新履歴

≪さらに古い更新履歴を展開する≫



標準ライブラリのリファレンス(名前順)のトップページへ

標準ライブラリのリファレンス(ヘッダ別)のトップページへ

C言語編のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Pocket に保存 Facebook でシェア
X で ポストフォロー LINE で送る noteで書く
rss1.0 取得ボタン RSS 管理者情報 プライバシーポリシー
先頭へ戻る