C言語の罠ポイント(文字列)
久しぶりに素のC言語。
やっぱりC言語の文字列周りは鬼門。
strcpyはバッファオーバーフローの危険があるから使わないようにってのはいいんだけど、対策として推奨されてるstrncpyがやっかい。
ダメパターン(バッファオーバーフローあり)
int _tmain(int argc, _TCHAR* argv[]) { char source[] = "teststrings"; char copyed[4]; strcpy(copyed, source); printf(copyed); return 0; }
とりあえず、strcpyをstrncpyにしてみます。
int _tmain(int argc, _TCHAR* argv[]) { char source[] = "teststrings"; char copyed[4]; strncpy(copyed, source, sizeof(copyed)); printf(copyed); return 0; }
これでバッファオーバーフローはない・・・のですが問題があります。
実行結果がこちら
printfで表示してる文字が4文字以上になっています。
これはstrncpyの動作に罠があって
strncpy関数
char *strncpy(char * restrict s1,const char * restrict s2,size_tn);
s2が指す配列からs1が指す配列に文字をコピーするが、n文字を超えてコピーはしない。また、NULL文字より後の文字はコピーしない。
よって、s2が指す配列の最初のn文字の中にNULL文字がなければ、s1に格納される文字列はNULLで終端されない。
ぎりぎりサイズまでコピーするとNULLで終端されないのでprintfがバッファを越えて、NULLがでてくるまで表示し続けたわけです。
ちゃんとやるならこんな感じでしょうか。
int _tmain(int argc, _TCHAR* argv[]) { char source[] = "teststrings"; char copyed[4]; strncpy(copyed, source, sizeof(copyed)); copyed[sizeof(copyed) - 1] = '\0'; printf(copyed); return 0; }
これ、忘れるよ・・・
参考:
sprintfのかわりのsnprintfはNULL終端されるのでこの問題は気にしなくてOK