A:
このプログラムは、非常に大きな(1キロバイトかそれ以上の)ローカ ルな配列を持っているはずだ。多くのシステムではスタックの大きさ は固定だし、(Unixのように)動的にスタックを自動的に確保するシス テムでもスタックのサイズが突然巨大になると、混乱する場合がある。 大きな配列を使うときはstaticと宣言したほうがいい(もちろん再帰 呼び出しするたびに新しい配列が必要な場合は除く。こういう場合は malloc()を使って動的に確保する。質問1.31を参照のこと)。
(質問11.12, 16.4, 16.5, 18.4も参照のこと)
A:
main()のプロトタイプ宣言のおかしくないかとか(質問2.18, 10.9参 照)、setbuf()とかsetvbuf()にローカルのバッファを渡してないかと か、atexit()に登録した後片付けの関数に間違いはないかを調べる。 質問7.5や11.16も参照のこと。
References:
CT&P Sec. 5.3 pp. 72-3.
A:
おかしくなる可能性のあるものはたくさんある。以下に可能性の高い ものをいくつか示す。
初期化してないローカル変数(質問7.1参照)
整数のオーバーフロー、特に16ビットマシンで、とりわけ a * b / cのような計算の中間結果の桁溢れ(質問3.14も参照 のこと)
external関数の宣言のし忘れ、特にint以外を返す関数で(質 問1.25と14.2参照)
ヌルポインターの間接参照(5章参照)
誤ったmalloc/freeの使い方。mallocしたメモリが全部0に なってるとかfreeした領域がまだ使えると思い込んだり、同 じものを2回freeすること(質問7.20や7.19を参照のこと)
ポインターの問題全般(質問16.8も参照のこと)
printf()の書式と実引数の不一致、特にlongの整数を%dを使っ て出力しようとする(質問12.9も参照)
malloc(256 * 256 * sizeof(double))を実行しようとする。 特にメモリの量が限られているマシンで(質問7.16と19.23 も参照のこと)
配列の境界の問題。特に小さな一時的バッファで、おそらく sprintf()を使って文字列を構築するのに使う(質問7.1と 12.21も参照)
typedefと実際のデータ型の対応の誤った思い込み。とりわ けsize_t
対象となる具体的なシステムで コードの生成されかたを決 め付けて、こういう使いかたを考え付くとは俺って頭がいい なと思っていることはなんでも
関数プロトタイプを適切に使うことで、これらの問題のかなりの部分 を捕まえることができる。lintを使えばもっと多くの問題を捕まえる ことができる。質問16.3, 16.4, 18.4も参照のこと。
char *p = "hello, world!"; p[0] = 'H';A:
文字列定数は、(ようするに)配列の初期化指定子として使われるとき を除いては、必ずしも変更可能ではない。以下の方法を試すこと。
char a[] = "hello, world!";質問1.32も参照のこと。
References:
ANSI Sec. 3.1.4; ISO Sec. 6.1.4; H&S Sec. 2.7.4 pp.
31-2.
A:
これらは一般に、アクセスすべきでない記憶領域にプログラムがアク セスしようとしたことを意味している。きっとポインターの使い方が 適切でなかったからに違いない。考えられる原因としては以下のもの が考えられる。
ヌルポインターの誤った使い方(質問5.2, 5.20も参照)。初期化され ていないポインター/境界の合ってないポインター/その他適切でない 確保のされかたのポインター(質問7.1と7.2参照)。mallocした領域が 壊れた(質問7.19参照)。関数引数の不一致、特にポインターが絡んだ 場合、2つ考えられるのはscanf()(質問12.12参照)とfprintf()(最初 のFILE *の引数を渡されていることを確認すること)。