0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ユーザの任意の入力文字列に合わせて動的にメモリを確保する

Last updated at Posted at 2025-03-17

経緯
mallocでメモリを確保する方法はわかったものの,プログラム実行中に自動でメモリ管理するようにして使わないと意味なくない?と思い,ユーザの任意の入力文字列に合わせて動的にメモリ確保する方法を調べていた.
ChatGPTがgetcharで1文字ずつ受け取る例を出力したためそれに対して以下の質問をした.

質問:「getcharで1文字ずつ読み取らなければreallocによる動的メモリ範囲の拡張はできないのですか?」
以下はChatGPTの回答.


getchar で1文字ずつ読み取らなくても、realloc を使って動的メモリを拡張することは可能です。入力のサイズを事前に把握する必要はなく、例えば fgets を使って一度にデータを読み取る場合でも、メモリの不足に応じて動的に拡張できます。

realloc による動的メモリの拡張は、文字列を逐次的に受け取る(1文字ずつ、または一括で)方法に依存しません。重要なのは「メモリのサイズが不足した場合に、その都度メモリを再確保する」処理が必要である点です。

以下に、getchar を使わず、fgetsscanf のような方法で、動的にメモリを拡張する実装例を紹介します。

例: fgets を使って動的メモリを拡張

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

int main() {
    char *input = NULL;
    int buf_size = 10;  // 初期バッファサイズ
    int length = 0;     // 入力文字列の長さ(ヌル文字を含む)
    
    // メモリの動的確保
    input = (char *)malloc(buf_size * sizeof(char));
    if (input == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    printf("Enter a string: ");
    
    // 入力を一度に読み取るが、バッファが足りない場合には再確保
    while (fgets(input + length, buf_size - length, stdin) != NULL) {
        // 改行文字が含まれているか確認
        length = strlen(input);

        if (input[length - 1] == '\n') {
            input[length - 1] = '\0';  // 改行をヌル文字に変換して終了
            break;  // 改行が含まれていたら入力終了
        }

        // バッファが足りなくなった場合にメモリを再確保
        buf_size *= 2;  // バッファサイズを倍増
        input = (char *)realloc(input, buf_size);
        if (input == NULL) {
            printf("Memory reallocation failed!\n");
            return 1;
        }
    }

    printf("You entered: %s\n", input);

    // 動的に確保したメモリを解放
    free(input);

    return 0;
}

実装のポイント

  1. fgets を使用して入力を一度に受け取る:

    • fgets を使って一度に複数の文字を読み取ります。fgets の引数で指定したバッファのサイズに応じて読み取りますが、もしバッファが足りない場合は、再度 realloc を使ってバッファを拡張します。
  2. realloc による動的メモリ拡張:

    • fgets の呼び出し後、文字列の長さ(strlen)をチェックし、改行文字が含まれていなければ、バッファサイズを倍増します。その後、再度 fgets を使って、残りの入力を読み取るためにメモリを拡張します。
  3. 改行文字の処理:

    • fgets は入力中の改行文字も読み込むため、改行文字を検出して、その場合に入力を終了する処理を加えています。

動的メモリ範囲の拡張の理解

fgetsscanf のような方法でも、入力が増えるたびに realloc でメモリを拡張することができます。重要なのは、バッファのサイズが足りなくなった時に、その都度メモリを再確保して範囲を広げていくことです。これにより、固定サイズのバッファを超えた入力を効率的に処理できます。

  • fgets を使う: 一度に複数の文字を入力でき、入力が終わったら改行を取り除く処理を加えます。
  • scanf を使う: scanf で入力のフォーマットを指定して処理しますが、fgets よりも柔軟性に欠けるため、複雑な入力には不向きです。

結論

  • getchar を使わずとも、fgetsscanf を使って動的にメモリを拡張することができます。重要なのは、入力を逐次的に受け取る(または一度に受け取る)ときに、メモリが不足した場合に realloc を使って拡張することです。
  • メモリの拡張が必要な場合、fgets のような関数で入力を一度に読み取ってから処理する方法が便利で、効率的です。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?