我正在编写一个简单的练习来比较 memcpy 或 strncpy 的用法。我发现我可以使用以下两个函数之一执行此字符串复制:
char * strncpy ( char * destination, const char * source, size_t num );
和
void * memcpy ( void * destination, const void * source, size_t num );
简单做法
char src[] = "Hello World";
char dst[20];
strncpy(dst, src, 5);
printf("%zu-", strlen(dst));
memcpy(dst, src, sizeof(dst));
printf("%zu-", strlen(dst));
strncpy(dst, src, 5);
printf("%zu", strlen(dst));
实际输出
5-11-11
我怎样才能理解他们在尊重方面有何不同?
一般来说,如何找出使用 memcpy 或 strncpy 复制的不同内存块的相对字节?
如果在源中找到空字符之前计数已用尽,
strncpy
则不会将终止空字符写入目标。则dst
可能不是以空字符终止的,在这种情况下的行为未定义。但是,打印“5”这一事实与恰好在中包含零strlen
是一致的。dst
dst[5]
你的
src
只有 12 个字节,而sizeof(dst)
有 20 个字节,因此它memcpy
会尝试读取超出 的字节src
。同样,此行为未定义。它可能会复制到dst
“Hello World”的 11 个字节、接下来的空字节,然后是 之后内存中的 8 个字节src
。此时,
dst
可能包含上面描述的数据,“Hello World”的 11 个字节以及接下来的空字节,这导致strlen
返回 11。strncpy
如果空间不足,则不会添加 NUL。由于strlen
需要以 NUL 结尾的字符串,因此第一次使用会strlen
导致未定义的行为。正确使用
strncpy
需要确保终止 NUL,您可以使用以下命令执行此操作:stpncpy
与 类似strncpy
,不同之处在于它返回指向停止写入的位置的指针,而不是用 NUL 填充缓冲区的其余部分。因此也可以使用以下内容:还有第二个问题。您
memcpy
尝试复制 20 个字节,但要复制的对象仅占用 12 个字节。所以这也是未定义的行为。不要复制超过您拥有的字节数!