strncpy_sではなくmemmoveを使え

strncpy_sはMicrosoftの拡張なので、memmoveを使った方が可搬性が良いとのことらしい。
細かいところはわかっていない。

memmoveとmemcpyの違いは、コピー元とコピー先の領域がかぶってもいいかどうかで、それ以外の挙動は同じ。
なので、かぶっても動作が担保されているmemmoveを基本的に使えばよい。
moveとついているので、コピー元が領域が担保されないように感じるがそんなことはない。

#include        <stdio.h>
#include        <string.h>

int main(void)
{
        char dst[7]{0};
        char src[] = "abcdef";
        
        memmove(dst, src, sizeof(dst));

        return 0;
}

ちなみに、第三引数にdstのサイズより大きいサイズを指定すると、バッファオーバーフローが起こる(ビルド時点でわかる場合は、そもそもビルドが通らなくなる)。
一方、srcのサイズより、大きいサイズを第三引数に指定してコピーしても特に問題はない(はず)。
なので、第三引数にsizeof(dst)を指定しておけば、srcからコピーできる範囲分、dstに安全にコピーできる。

なお、dstを文字列として扱う場合、dstを事前に

char dst[7]{0};

で明示的にゼロクリアしておかないと、memmove後に、dstがヌル終端にならないケースがあるので注意。
dstを文字列として扱う場合は、ヌル終端を上書きしてしまわないように、

int main(void)
{
        char dst[7]{0};
        char src[] = "abcdef";
        
        memmove(dst, src, sizeof(dst)-1);

        return 0;
}

とした方がよい。

環境依存による可搬性の話を無視するなら、ヌル終端を意識するのが面倒なので、文字列コピーの場合はstrncpy_s()を使う方法がよさそう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です