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()を使う方法がよさそう。
 
 
コメントを残す