導入
malloc で確保したメモリの中身は不定(ゴミが入っている可能性がある)です。最初から 0 にしておきたいときは calloc を使います。また「最初は3個で確保したが、後から5個に増やしたい」というときは realloc で確保済みの領域を拡張できます。
説明
calloc(個数, 1個のバイト数) は、確保と同時に全バイトを 0 にします。realloc(元のポインタ, 新しいバイト数) は、元のデータを保ったまま領域を大きく(または小さく)します。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *arr = calloc(3, sizeof(int)); // 0, 0, 0 で確保される
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr = realloc(arr, 5 * sizeof(int)); // 5個分に拡張(元の1,2,3は保たれる)
if (arr == NULL) {
printf("失敗\n");
return 1;
}
arr[3] = 4;
arr[4] = 5;
int i, sum = 0;
for (i = 0; i < 5; i++) {
sum += arr[i];
}
printf("合計=%d\n", sum);
free(arr);
return 0;
}
realloc は「必ずしも同じ場所を拡張してくれる」わけではありません。空きが足りない場合は、内部で新しい場所にコピーしてから古い領域を解放し、新しいアドレスを返します。だから 必ず戻り値を受け取り直す(arr = realloc(arr, ...))必要があります。
flowchart LR a["calloc(3, sizeof(int))<br/>0,0,0で確保"] --> b["1,2,3 を代入"] b --> c["realloc(arr, 5*sizeof(int))"] c --> d["1,2,3は保たれ<br/>4,5番目が使えるようになる"] c -.->|"空きが足りない場合"| e["別の場所にコピーして<br/>新しいアドレスを返す"]
やってみよう
realloc の拡張先のサイズをさらに大きくしてみたり、calloc で確保した直後に arr[0] を表示して 0 になっていることを確かめましょう(malloc だとゴミが入っている可能性があります)。
演習
calloc で {10, 20, 30} の3要素を確保し、realloc で6要素に拡張してください。追加した3つの要素には 40, 50, 60 を入れ、6要素の合計を printf("合計=%d\n", sum); の形で表示してください(正しく書けると 合計=210 になります)。最後に free で解放してください。
ヒント1を見る
arr = realloc(arr, 6 * sizeof(int)); で6個分に拡張します。
ヒント2を見る
arr[3] = 40; arr[4] = 50; arr[5] = 60; を追加してから合計します。