文字列にはstrncpyを使えばokなどと思考停止しながら書いていたらハマったのでメモ
概要
strncpyの挙動は以下の通りです。
- コピー元の文字列の長さが指定された文字列以上の場合、指定分コピーする この時ナル文字は付加しない
- コピー元の文字列の長さが指定された文字列未満の場合、指定分コピーする この時余った部分にはナル文字を埋め込む
strncpyで利用を想定されているのは文字列なので、これらの文面は終端にナル文字が付加されている配列と言うのが前提です
その為末尾にナル文字が付加されていない配列に対して使えば当然範囲外参照になります
例
具体的には以下のような感じです
test.c
#include <stdio.h>
#include <string.h>
//以下のコードは違反コードです
//動かす際には注意してください
int main(){
char str1[] = "hogehogehoge";
char str2[sizeof(str1) + 2];
char str3[sizeof(str1) - 2];
//OK str1以上のサイズが確保されているため空いたスペースにはナル文字が付加される
strncpy(str2,str1,sizeof(str2));
//これもOK ただし末尾にナル文字は付加されない
strncpy(str3,str1,sizeof(str3));
//NG str3にナル文字は付加されていないので範囲外参照してしまう
strncpy(str2,str3,sizeof(str2));
printf("%s\n%s\n%s\n",str1,str2,str3);
return 0;
}
1番目と2番目のstrncpy呼び出しでは正常に動作しますが、2番目のstrncpyだけサイズが足りておらず
ナル文字が付加されずに終了します
そして3番目のstrncpy呼び出しではナル文字の付加されていない文字列をコピーしようとしたため範囲外参照となってしまいます。
結論
気を付けます