中級のC言語エラー 39問
13種類のエラーを、それぞれ複数パターンずつ収録しています。
- sizeofが配列の要素数ではなくポインタのサイズを返す配列に対するsizeofは配列全体のバイト数を返しますが、関数の引数として渡された配列はポインタに変わっているため、同じsizeofが8(ポインタのサイズ)を返してしまいます。
- Segmentation fault(strcpyによるバッファオーバーフロー)コピー先のchar配列より長い文字列をstrcpyでコピーすると、確保した領域を超えて書き込みが起こります。隣接するメモリを破壊し、クラッシュにつながります。
- strcmpの戻り値を真偽値と勘違いして条件が逆になるstrcmpは文字列が等しいときに0を返します。if (strcmp(a, b))と書くと「等しくないとき」に真になり、多くの人が期待する「等しいとき」とは逆の分岐になります。
- ビット演算子 & の優先順位が比較演算子 == より低いことによる誤動作a & b == cと書くと、==の方が優先順位が高いため、a & (b == c)として解釈されます。意図した(a & b) == cとは異なる結果になります。
- switch文でbreakを忘れて次のcaseまで実行される(フォールスルー)各caseの末尾にbreakが無いと、一致したcase以降のブロックがそのまま次のcaseに流れ込んで実行され続けます。
- error: invalid operands to binary ==(構造体同士の==比較)構造体同士を==で比較しようとしたときに出るエラーです。Cの==は組み込み型専用で、構造体には定義されていません。
- error: assignment of read-only variable の原因と直し方constをつけて宣言した変数に、後から値を代入しようとしたときに出るエラーです。constは「一度決めたら変更不可」を意味します。
- error: assignment of read-only location の原因と直し方const int *pのように「指す先が変更不可」なポインタを介して、*pに値を書き込もうとしたときに出るエラーです。
- Segmentation fault(scanfで&を付け忘れる)scanfは書き込み先のアドレスを受け取る関数です。scanf("%d", x)のように&を付け忘れると、変数の値そのものを不正なアドレスとして書き込もうとし、クラッシュします。
- 多次元配列で行と列の添字を取り違えて違う値を読むarr[row][col]とarr[col][row]は多くの場合どちらもコンパイルは通り実行もできますが、正方でない配列では違う位置の値を読んでしまいます。
- 関数内のローカル変数のアドレスを返すと解放済み領域を指す関数の中で宣言したローカル変数は、その関数を抜けると同時に領域が無効になります。そのアドレスをreturnで返すと、呼び出し元は既に無効な領域を指すポインタを受け取ります。
- 符号ありと符号なしの比較で -1 が巨大な数として扱われるint型とunsigned int型を比較すると、int型の値は自動的にunsigned intへ変換されます。負の数は非常に大きな正の数として扱われ、直感に反する比較結果になります。
- int型の最大値に1を足すと最小値(負の数)に折り返るINT_MAXに1を足すと、多くの環境ではINT_MINまで折り返り、突然大きな正の数が大きな負の数に変わります。