目次
バッファーオーバーフロー
コードに誤りが見られないのに誤作動するとき、バッファーオーバーフローが原因かもしれません。特に変数の値が意図せず変わるなら、真っ先にバッファーオーバーフローを疑ってください。
sprintf関数①
配列のサイズを超える文字列を代入してはいけません。
[不適合例]
char buf[5];
int line = 5;
sprintf(buf, "line=%d", line);[適合例]
char buf[10]; // 十分大きいサイズにする
int line = 5;
sprintf(buf, "line=%d", line);sprintf関数②
sprintf関数は末尾にNULLが入ります。これを考慮せずに使用すると、NULLがバッファーオーバーフローを引き起こします。これを避けるため配列のサイズはdefineで定義し、変数宣言では「+1」すると良いでしょう。
[適合例]
#define NAME_SIZE (12)
char name[NAME_SIZE + 1];
int year = 2000;
int month = 1;
int day = 1;
sprintf(name, "%04d%02d%02d.txt", year, month, day);配列のサイズを超えないように監視する
通信データの受信を行う場合、受信データが配列のサイズを超えないように監視しなければなりません。
[適合例]
#define COM_SIZE (12)
#define CR (0x0D)
char com_data[COM_SIZE];
int size = 0;
int flag = 0;
while (1) {
com_data[size] = sci_getch();
if (com_data[size] == (char)CR) {
break;
}
size++;
// バッファーオーバーフローの監視
if (size >= COM_SIZE) {
flag = 1;
break;
}
...
}演算誤差
整数除算
演算結果に妙な誤差が発生するとき、整数どうしの除算を行っている可能性があります。浮動小数点数にキャストして演算してください。
[不適合例]
int a = 3;
int b = 2;
double c, d;
c = a / b; // c = 1
d = 3 / 2 * c; // d = 1[適合例]
int a = 3;
int b = 2;
double c, d;
c = (double)a / b; // c = 1.5
d = 3.0 / 2.0 * c; // d = 2.25
あわせて読みたい


整数型は単純なようで難しい | C言語
整数型は単純なようで処理系によって型のサイズが異なったり、演算では拡張されたりなどやっかいな性質をもっています。これらの性質を正しく理解したうえで使用しない...
オーバーフロー
演算結果がまったく想定していない値になるとき、オーバーフローしている可能性があります。型のサイズを大きくするか、キャストして演算してください。
[不適合例]
// int型が2バイト、符号付き整数が2の補数の処理系とする
int a = 32767;
int b = 1;
long c;
c = a + b; // c = -32768[適合例]
int a = 32767;
int b = 1;
long c;
c = (unsigned long)a + b; // c = 32768
コメント