ルギア君の戯言

雑多な記事。

malloc

C言語のお話。


下のソースコードを眺めてください。

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

// (中略)

unsigned char* screen;
int i;

// (中略)

screen = (unsigned char*) malloc(200);  // (1)
if(screen = NULL) {                     // (2)
    printf("Memory Allocation Error."); // (3)
    exit(EXIT_FAILURE);                 // (4)
}                                       // (5)
for(i = 0; i < 200; i++) {              // (6)
    screen[i] = 0;                      // (7) ここでクラッシュする
}                                       // (8)

// (後略)

ここで、問題です。

上のプログラムは間違っています。
みなさんは、このプログラムのどこが間違っているかわかりますか?


クラッシュする場所は上のコメントのように突き止めてありますが、デバッガを持っていないので、それ以外の情報はわかりません。


答えは「続きをよむ」

間違っている行は (2) でした。


(2) の行で screen が NULL になるので、NULL ポインタへの代入はエラー(原因が分かりにくいクラッシュ)になってしまうのです。


Linux だと「Segmentation fault.」とでるところなのですが*1、Windows の場合「このプログラムは不正な処理を行ったので・・・」としか出ず、(もしかしたら「技術情報」のところに出てくるのかもしれないが、)何度修正してもうまくいかず、間違った行(2) を見つけるのに 2時間かかってしまったという始末にいたってしまったのだ。


ちなみに、NULL は 0 つまり FALSE ですから (3) と (4) はスキップしますよ。


これは誰でもやる間違いだと思うので、みなさんも気をつけてくださいね(ぁ


↓は常識的な話。

エラーが起きたとき(「Segmentation fault」や「このプログラムは不正な処理を行ったので・・・」の場合は特に)すること

  1. エラーの場所を突き止める (プログラム側から明らかにわかるエラーには行番号を一緒に出力させるとよい)
  2. エラーの原因を突き止める (プログラム側から明らかにわかるエラーは確信を持って出力したエラーメッセージがそのまま原因と見て 80% 以上は問題ない*2 )
    • 今回のような(タイプミスなどによる)潜在的なエラーの場合は広い目でみる必要がある。時には 10000 行離れたところに原因がある可能性もあり得る。
  3. エラーを修復する (エラーの内容によってはプログラムには問題がないこともある (例: ファイルシステムのエラー*3 ))

*1:僕が勝手に「Segmentation fault.」をポインタ系統のエラーだと決めつけている

*2:そのときは同時に、エラーメッセージを出す条件が間違っていないかも確認する。

*3:「ファイルが見つからない」とか「アクセス権限がない」などなど