C言語関数:realloc





C言語のページでは、次の内容を解説しております。
C言語の入門講座  C言語の文法を中心に、基本的な関数などの解説をしています。
C言語ケーススタディ  C言語での実践的なプログラミングについて解説をしています。
C言語の関数リファレンス  C言語で用意されている関数を解説しています。
C言語で3次元動画プログラム  C言語で3次元タートルグラフィックを使用した3次元の動画プログラムの作成例です。
C言語の検定試験  C言語の文法に関する検定試験を実施することができます。
C言語でゲーム作成  C言語を使用したゲームの作り方を解説したページも用意しております。



2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を協力にサポートします。
ブロック崩しゲーム 3Dツリー クリスマスツリー
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study Cにロードする Study Cにロードし編集する Study Cにロードし実行する
Study C無料利用についての詳細は、このページを参照してください。




■realloc
メモリ割り当ての変更

【分類】
メモリ関数

【書式】
void *realloc(void *block, unsigned size);

【パラメータの型と説明】

パラメータ説明
void *block確保されているメモリブロック
unsigned size確保するオブジェクトのサイズ

【機能説明】
blockで指定したメモリブロック(malloc関数などですでに割り当てられている)のサイズを変更します。
メモリブロック内に書き込まれている内容は、新しいメモリブロックにコピーされます。
返り値として新しいメモリブロックの先頭アドレスを返します。
メモリが不足してメモリブロックが確保できない場合はNULLを返します。
blockがNULLの場合は、単に新しいメモリブロックを割り当てます(malloc関数と同じ機能)。
また、sizeが0の場合は、blockで指定したメモリブロックは解放されNULLを返します。
すでに割り当てられているメモリブロックと新たに割り当てられたメモリブロックは同じアドレスとは限りません。

calloc()関数の使用例です。
「test.txt」というファイルの内容を読み込むプログラムです。 実行する前に、ファイルを作成しておく必要があります。 次のコマンドでファイルを作成してください。

C:\StudyC\MyProg>echo long line 1111111111222222222233333333334444444444>test.txt

C:\StudyC\MyProg>echo line add>>test.txt

C:\StudyC\MyProg>type test.txt
test file
line add
#include <stdio.h>

main()
{
        FILE    *fp;
        char    buff[10+1];
        char    *line;
        int     len;
        int     total;

        fp = fopen("test.txt", "r");
        if (fp == NULL)
        {
                printf("ファイルオープンエラー\n");
                return;
        }

        total = 0;
        line = NULL;
        for (;;)
        {
                if (fgets(buff, 10, fp) == NULL)
                {
                        printf("ファイル終了\n");
                        break;
                }
                len = strlen(buff);
                printf("行データ追加:%s\n", buff);
                line = realloc(line, total + len + 1);
                if (line == NULL)
                {
                       printf("realloc()エラー\n");
                       break;
                }
                strcpy(line + total, buff);
                total += len;
                if (len > 0 && buff[len - 1] == '\n')
                {
                        printf("1行終了\n");
                        break;
                }
        }
        printf("行データ:%s", line);

        fclose(fp);
}

実行結果は以下になります。

行データ追加:long line
行データ追加: 11111111
行データ追加:112222222
行データ追加:222333333
行データ追加:333344444
行データ追加:44444

1行終了
行データ:long line 1111111111222222222233333333334444444444

1.fopen()関数で「test.txt」ファイルをオープンします。
「ファイルオープンエラー」と表示される場合は、事前にファイルが作成できていない可能性があるので確認してください。
2.forループ内でfgets()関数を使いファイル「test.txt」の内容を1行読み込みます(最大10バイト)。
長い行を読み込むプログラム例ですが、長い行を作るのも手間なので最大文字数を10バイトと小さくしました。
3.strlen()関数で読み込んだ文字列のバイト数を取得します。
4.取得した文字列のサイズと今までに読み込んだ文字列のサイズを合計し、そのサイズでrealloc()関数を呼び出します。
5.読み込んだ文字列をprintf()関数で表示します。
6.今までに読み込んだ文字列の最後にstrcpy()関数で文字列をコピー(追加)します。
7.変数total(今まで読み込んだ文字列のバイト数)に今回読み込んだ文字数を加算します。
8.読み込んだ文字列の最後が改行文字(\n)か調べ、もし改行文字ならforループを終了します(そうでない場合はforループを継続します)。
9.forループを抜けたら、printf()関数で読み込んだ1行の内容を表示します。

このように、1行を読み込むのは結構大変な処理となります。
fgets()関数の最大文字数を100バイトとかにすれば良いと思われるかもしれません。 しかし、101文字の行があったら1行として読み込むことができません。 同様に最大文字数を1000バイトにしても1001文字の行があったら1行として読み込むことができません。
このようにfgets()関数の最大文字数を大きくしていってもきりがありません。
C言語では、realloc()関数やmalloc()関数を使って可変サイズの読み込みを行うのが一般的です。

【参照関数】
calloc
malloc
free