C 言語で配列を動的に割り当てる

胡金庫 2023年10月12日
  1. 関数 malloc を使って C 言語で配列を動的に割り当てる
  2. 関数 realloc を用いて C 言語で既に割り当てられたメモリ領域を変更する
  3. C 言語で与えられたオブジェクトの配列に対する割り当てを実装する
C 言語で配列を動的に割り当てる

この記事では、C 言語で配列を動的に割り当てる方法の複数の方法を示します。

関数 malloc を使って C 言語で配列を動的に割り当てる

関数 malloc はヒープ上の動的メモリを確保するためのコア関数です。与えられたバイト数を確保し、メモリ領域へのポインタを返します。したがって、特定のオブジェクト型の配列を動的に確保したい場合は、まずその型へのポインタを宣言しなければならません。次に、引数にオブジェクトのサイズを掛けた要素数を渡して malloc を呼び出します。

次の例では、文字列を格納するためのメモリを確保しています。セキュアコーディング標準で要求されているように errno に 0 を設定し、malloc コールから返されたポインタをチェックして関数の実行が正常に行われたかどうかを確認します。最後に、memove 関数を用いて文字列を確保したメモリにコピーします。

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

#define SIZE 100

const char *str = "random string to be moved";

int main() {
  char *arr = NULL;

  errno = 0;
  arr = malloc(SIZE * sizeof(char));
  if (!arr) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  memmove(arr, str, strlen(str));
  printf("arr: %s\n", arr);

  free(arr);
  exit(EXIT_SUCCESS);
}

出力:

arr: random string to be moved

関数 realloc を用いて C 言語で既に割り当てられたメモリ領域を変更する

関数 realloc は、malloc コールで以前に割り当てられたメモリ領域のサイズを変更するために使用されます。この関数は元のメモリアドレスと新しいサイズを第 2 引数に取ります。realloc は、要求されたサイズと指定されたアドレス以降の利用可能なメモリに応じて、渡されたものと同じポインタを返すこともあれば、異なるポインタを返すこともあることに注意してください。一方、前の配列の内容は、新たに指定されたサイズまで変更されません。

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

#define SIZE 100

const char *str = "random string to be moved";

int main() {
  char *arr = NULL;

  errno = 0;
  arr = malloc(SIZE);
  if (!arr) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  int num = 102;  // User Provided Value
  for (int i = 0; i < num; ++i) {
    if (i > SIZE) {
      arr = realloc(arr, 2 * SIZE);

      if (!arr) {
        perror("realloc");
        exit(EXIT_FAILURE);
      }
    }

    arr[i] = 'a';
  }

  free(arr);
  exit(EXIT_SUCCESS);
}

C 言語で与えられたオブジェクトの配列に対する割り当てを実装する

通常、malloc はユーザ定義の構造体の配列を確保するために用いられます。mallocvoid ポインタを返し、暗黙的に他の型にキャストすることができるので、返されたポインタを対応する型に明示的にキャストするのが良い方法です。見落としがちなことや適切な記法が含まれていないことが比較的容易なので、配列の要素数とオブジェクトの型を取得して、適切なキャストを含めて正しい malloc 文を自動的に構築するマクロ式を実装しました。

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

#define SIZE 100

typedef enum {
  Jan,
  Feb,
  MAR,
  APR,
  MAY,
  JUN,
  JUL,
  AUG,
  SEP,
  OCT,
  NOV,
  DEC
} month;

typedef struct {
  unsigned char dd;
  month mm;
  unsigned yy;
} date;

#define MALLOC_ARRAY(number, type) ((type *)malloc((number) * sizeof(type)))

int main() {
  date *d = NULL;

  errno = 0;
  d = MALLOC_ARRAY(SIZE, date);
  if (!d) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  free(d);
  exit(EXIT_SUCCESS);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C Array