■静的解析で敵を見つける
●gcc -Wall -Wextra -Oでコンパイルして警告を直す
clang -Wall -Wextra -Oでもコンパイルして
警告を直しましょう。
●gcc -fanalyzer -O2でコンパイルして警告を直す
clang –analyze -O2でもコンパイルして
警告を直しましょう。
●clang-tidyやcppcheckも使ってみる
使い方はこちら。
ここまでやって問題解決できない場合
静的解析はあきらめましょう。
■動的解析で敵を見つける
●gccの場合
gcc -fsanitize=address -g でコンパイルして実行してください。
●clangの場合
clang -fsanitize=address -g でコンパイルして実行してください。
以下のようにエラー個所(ファイル名行番号)を教えてくれます。
-gオプションを付けないと行番号までは教えてくれません。
-Oオプション(最適化)の有無でエラーが出たり出なかったりする時があります。
前略
SUMMARY: AddressSanitizer: heap-buffer-overflow /mnt/中略/x.c:10 in main
後略
■敵 segmentation faultはこんな時出ます
出ない時もあります。
再現性が無いので苦労します。
●未初期化ポインタを間接参照しない事
#include <stdio.h>
#include <stdlib.h>
int main(void){
int x ;
int *p ; //未初期化ポインタ
x = 1234 ;
*p = 5678 ;
char *str; //未初期化ポインタ
printf("数字を入れてね");
scanf("%s",str);
printf("%d\n",atoi(str));
}
●NULLポインタを間接参照しない事
#include <stdio.h>
int main(void){
char x = '\0';
char *p = NULL;
x = 'A' ;
*p = 'B' ;//NULLポインタ間接参照
printf("%c:%c\n",x,*p);
}
●配列の添字が大きすぎる(基本を勉強)
#include <stdio.h>
int main(void){
int buf[10] = {1,2,3,4,5,6,7,8,9,10};
//buf[10]で宣言したらbuf[9]までしか使えない
printf("%d\n",buf[10]);
}
●配列の添字が大きすぎる(for文回り過ぎ)
#include <stdio.h>
int main(void){
int buf[10];
// int i = 0; i < 10;i++){ が正解
for(int i = 1; i <= 10;i++){
buf[i] = i;
}
printf("%d\n",buf[0]);
}
●自動変数配列のサイズが大きすぎる
#include <stdio.h>
int main(void){
//自動変数配列のサイズが多き過ぎる
char buf[0x7FFFffff] = {0};
printf("%d\n",buf[0]);
}
●fclose(NULL)を実行しちゃ駄目
#include <stdio.h>
int main(void){
FILE *fp = fopen("存在しなファイル","re");
if(fp == NULL){
perror(NULL);
fclose(fp);
}
}
●fgets()のバッファが小さすぎ(ケチらない事)
#include <stdio.h>
#include <stdlib.h>
int main(void){
//終端文字の考慮がない。
//ピッタリサイズでなくて余裕を持たせる。
char buf[4];
printf("4桁の数字を入れて下さい");
fgets(buf,BUFSIZ,stdin);
printf("%d\n",atoi(buf));
}
●malloc()で確保したサイズが小さい(型違い)
#include <stdio.h>
#include <stdlib.h>
int main(void){
//sizeof(int)はsizeof(double)の間違い
double *p = malloc(sizeof(int));
if(p == NULL){
perror(NULL);
return 1;
}
*p = 3.14 ;
printf("%lf\n",*p);
free(p);
}
●文字列リテラルへに書いちゃ駄目
#include <stdio.h>
int main(void){
char *p = "string" ;
*p = 'X' ;
}