使用memcpy而不是strncpy或类似的做法是否不好?

使用memcpy而不是strncpy或类似的做法是否不好?,c,string,C,String,在缓冲区之间移动字符串时,我经常将char*视为数据缓冲区,并且不使用任何字符串缓冲区(strncpy,strncat,等等)。 例如: memcpy(target, src, strlen(src) + 1) // after buffer size checks //vs strncpy(target, src, target_size - 1); target[target_size - 1] = 0; 这种做法不好吗 编辑:我知道区别,这不是重复,而是标准实践的问题。使用 memcpy

在缓冲区之间移动字符串时,我经常将
char*
视为数据缓冲区,并且不使用任何字符串缓冲区(
strncpy
strncat
,等等)。 例如:

memcpy(target, src, strlen(src) + 1) // after buffer size checks
//vs
strncpy(target, src, target_size - 1);
target[target_size - 1] = 0;
这种做法不好吗

编辑:我知道区别,这不是重复,而是标准实践的问题。

使用

memcpy(target, src, strlen(src) + 1) // after buffer size checks
可能需要遍历字符串两次,一次在
strlen
中,一次在
memcpy
中。如果使用strcpy,您会受到一点性能上的影响,而这一点是您没有的

如果您出于不相关的原因计算字符串的长度,或者从其他资源获得字符串的长度,我不清楚
memcpy
strncpy
好还是坏

如果您由于其他原因没有计算字符串的长度,或者没有来自其他资源的字符串长度,最好使用
strcpy
,而不是
memcpy
strncpy
使用

memcpy(target, src, strlen(src) + 1) // after buffer size checks
可能需要遍历字符串两次,一次在
strlen
中,一次在
memcpy
中。如果使用strcpy,您会受到一点性能上的影响,而这一点是您没有的

如果您出于不相关的原因计算字符串的长度,或者从其他资源获得字符串的长度,我不清楚
memcpy
strncpy
好还是坏


如果您由于其他原因没有计算字符串的长度,或者没有来自其他资源的字符串长度,最好使用
strcpy
,而不是
memcpy
strncpy
,如果您知道语义和大小,这不是问题。请记住,strncpy将在第一个空字节处停止,如果字符串较短,则还会用空字节填充目标中最多n个字符的以下字节(如果源中没有空字节,则不会写入空字节)。strncpy还可以为您提供一点更好的类型检查,因为它希望在所有情况下都使用
char*
,而不是
void*


哪个效率更高有待讨论,但基于CPU批量指令,它可以在一条指令中复制整个内存块,memcpy可能更快,因为strncpy会检查每个复制的字节是否有
NUL
字符。

如果您知道语义和大小,这不是问题。请记住,strncpy将在第一个空字节处停止,如果字符串较短,则还会用空字节填充目标中最多n个字符的以下字节(如果源中没有空字节,则不会写入空字节)。strncpy还可以为您提供一点更好的类型检查,因为它希望在所有情况下都使用
char*
,而不是
void*


哪个效率更高有待讨论,但基于CPU批量指令,它可以在一条指令中复制整个内存块,memcpy可能更快,因为strncpy会检查每个复制的字节是否有
NUL
字符。

假设您授予
target
大小至少为strlen(src)+1字节长,这样做没有什么害处。如果您知道字符串的长度,那么
memmove()
memcpy()
是一种很好的做法,尽管使用频率不如它可能/应该的那样高。如果您不知道字符串的长度,
str*()
例程通常是一场灾难,
strncat()
strncpy()
更糟糕,但差距不大。
memcpy()
将写入
strlen(src)+1个字符<代码>strncpy(目标,src,目标大小-1);目标[目标大小-1]=0将写入
目标大小
字符。重要提示:字符串长度是否应该像1024个缓冲区那样大,以便复制
“abc”
@JonathanLeffler:在什么意义上
strncat
strncpy
更糟糕?(顺便说一句,.)假设
target
的大小至少为strlen(src)+1字节长,那么这样做没有什么坏处。如果您知道字符串的长度,那么
memmove()
memcpy()
是一种很好的做法,尽管使用频率不如可能/应该的那样高。如果您不知道字符串的长度,
str*()
例程通常是一场灾难,
strncat()
strncpy()
更糟糕,但差距不大。
memcpy()
将写入
strlen(src)+1个字符<代码>strncpy(目标,src,目标大小-1);目标[目标大小-1]=0将写入
目标大小
字符。重要提示:字符串长度是否应该像1024个缓冲区那样大,以便复制
“abc”
@JonathanLeffler:在什么意义上
strncat
strncpy
更糟糕?(顺便说一句,.)OP的可能副本询问了一个
strncpy()
比较。非常正确,我发现使用大字符串时,我已经知道了其他地方的长度,谢天谢地。@Taywee,
strlen
也会有问题,在使用
memcpy
之前需要使用它。如果在开始复制之前不知道字符串的长度,则无法使用
strcpy()
安全地复制它(并且使用
memmove()
memcpy()
)。这就是缓冲区溢出的工作原理-实际字符串比预期的长(通常长得多)。@Taywee,发布的代码在调用
memcpy
时使用了
strlen
。OP询问了
strncpy()
比较。非常正确,我发现使用大字符串时,我已经从其他地方知道了长度,谢天谢地。@Taywee,
strlen
也会有问题,在使用
memcpy
之前需要使用它。如果在开始复制之前不知道字符串的长度,则无法使用
strcpy()
安全地复制它(并且无法使用
mem复制它)