2016/12/01

[c/c++]strncatはあふれても\0付加しない

一番使っているのはC/C++だが、文字列を扱うことがあまりないので、標準関数が苦手だ。
特に、バッファがぎりぎりしかないときの扱いは、いつも不安なので事前にテストコードを書いている。

昨日書いていて、気付かないままバッファあふれしていたので、調べておこう。
cygwinのgcc 5.4だ。


#include 
#include 

int main(int argc, char *argv[])
{
    static char str[3];

    memset(str, '*', sizeof(str));
    snprintf(str, sizeof(str), "123456");
    printf("snprintf=[%s]\n", str);

    memset(str, '*', sizeof(str));
    strncpy(str, "123456", sizeof(str));
    printf("strncpy=[%s]\n", str);

    strncat(str, "123456", sizeof(str));
    printf("strncat=[%s]\n", str);

    return 0;
}

さて、結果はおわかりだろうか?

 

 

snprintf=[12]
strncpy=[123]
strncat=[123123]

strncpy()やstrncat()が\0を付加しないというのは覚えていたのだが、strncat()のnは追加する文字列に対してのもので、バッファ全体に対してのものじゃないのだな。。。
ポインタの先頭から\0を探して、そこから追加していくから、その時点でnに達していたら追加は行わないかと思っていた・・・。
危ないところだった。

 

その回避をしたい場合は、C11から追加された_s系の関数になる。
strncpy_s()やstrncat_s()だ。
こっちはsnprintf()のように、第2引数にバッファのサイズを指定するのだ。

試してみたかったのだが、このgccではc11オプションを付けてもダメだった。
strcpy, strcpy_s - cppreference.com
__STDC_WANT_LIB_EXT1__を1に定義してからコードを書き始めるのだが、__STDC_LIB_EXT1__が未定義だから、そもそも使用できないようだ。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。