C 言語でのフリーの無効なポインタエラーの修正

胡金庫 2023年10月12日
  1. 非動的メモリ位置を指す free ポインタではありません
  2. 既に解放されているポインタを free しない
C 言語でのフリーの無効なポインタエラーの修正

この記事では、C 言語で free の無効なポインタエラーを修正する方法について、複数の方法を紹介します。

非動的メモリ位置を指す free ポインタではありません

free 関数呼び出しは、malloccallocrealloc 関数が返したポインタからメモリを解放するためにのみ使用されるべきです。以下のコードは、char* ポインタに malloc コールから返された値を代入したが、後に else ブロックの中で同じポインタに文字列リテラルが代入されてしまうというシナリオを示しています。これは、c_str 変数が動的メモリ領域ではない場所を指していることを意味し、free 関数に渡すことはできません。その結果、次の例を実行して free 関数の呼び出しに到達すると、プログラムは中断され、free(): invalid pointer エラーが表示されます。

元の場所を指している他のポインタ変数が存在しない限り、異なるアドレスを持つ動的メモリの場所へのポインタを再割り当てしてはならないことに注意してください。最後に、ヒープメモリを指すポインタに対してのみ free 関数を呼び出すべきです。

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

int main(int argc, const char *argv[]) {
  char *c_str = NULL;
  size_t len;

  if (argc != 2) {
    printf("Usage: ./program string\n");
    exit(EXIT_FAILURE);
  }

  if ((len = strlen(argv[1])) >= 4) {
    c_str = (char *)malloc(len);

    if (!c_str) {
      perror("malloc");
    }

    strcpy(c_str, argv[1]);
    printf("%s\n", c_str);
  } else {
    c_str = "Some Literal String";
    printf("%s\n", c_str);
  }
  free(c_str);

  exit(EXIT_SUCCESS);
}

既に解放されているポインタを free しない

ダイナミックメモリを使用する際のもう一つの一般的なエラーは、既に解放されているポインタに対して free 関数を呼び出すことです。このシナリオは、同じダイナミックメモリ領域を指す複数のポインタ変数がある場合に起こりやすいです。以下のサンプルコードは、同じ場所が異なるスコープで解放される、そのようなケースを示しています。

この例は単一ファイルのショートプログラムであり、このような問題を診断するのは簡単ですが、大規模なコードベースでは、静的解析を行う外部のインスペクタプログラムがないと、ソースを追跡するのが難しいことに気づくかもしれません。

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

int main(int argc, const char *argv[]) {
  char *c_str = NULL;
  size_t len;

  if (argc != 2) {
    printf("Usage: ./program string\n");
    exit(EXIT_FAILURE);
  }
  char *s = NULL;

  if ((len = strlen(argv[1])) >= 4) {
    c_str = (char *)malloc(len);
    s = c_str;

    if (!c_str) {
      perror("malloc");
    }

    strcpy(c_str, argv[1]);
    printf("%s\n", c_str);
    free(c_str);
  } else {
    c_str = "Some Literal String";
    printf("%s\n", c_str);
  }
  free(s);

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

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

LinkedIn Facebook

関連記事 - C Pointer