2016-07-07 118 views
0

在缓冲区之间移动字符串时,我经常将char*当作数据缓冲区,并且不使用字符串缓冲区(strncpystrncat等)。 例如:使用memcpy而不是strncpy或类似的做法是不好的做法?

memcpy(target, src, strlen(src) + 1) // after buffer size checks 
//vs 
strncpy(target, src, target_size - 1); 
target[target_size - 1] = 0; 

这是不好的做法?

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

+0

假设您授予'target'大小至少为strlen(src)+ 1个字节长,这样做没有任何坏处。 – pah

+1

如果你知道字符串的长度,那么'memmove()'或'memcpy()'是很好的习惯 - 虽然不是它可以/应该被经常使用。如果你不知道字符串的长度,那么'str *()'例程通常是一场灾难,'strncat()'比它更糟糕,但不会有太大的差距。 –

+0

'memcpy()'会写入'strlen(src)+ 1'字符。 'strncpy(target,src,target_size - 1); target [target_size - 1] = 0;'将写入'target_size'字符。重要的是字符串的长度应该像1024缓冲区的“abc”副本一样大。 – chux

回答

1

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

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

+1

“strncpy将停在第一个空值处” - > no。它不止于此。它的大小填满了目标基础。 – chux

+0

你是对的:'如果src的长度小于n,则strncpy()向dest写入额外的空字节,以确保总共写入n个字节。' – Taywee

+0

'memcpy()'可以更快,因为它不需要像'strncpy()一样写目标缓冲区的大小,直到字符串长度。用小字符串/缓冲区关心,但大缓冲区和各种长度的字符串可以节省很多。 – chux

3

使用

memcpy(target, src, strlen(src) + 1) // after buffer size checks 

可能包括遍历字符串两次 - 在memcpy一次strlen一次。如果您使用strcpy,那么您的演奏效果会很差。

如果由于不相关的原因计算字符串的长度或从其他资源获取字符串的长度,我们不清楚memcpy是否好于或低于strncpy

如果不计算字符串因其他原因的长度或没有来自其他资源的字符串的长度,它是更好地使用strcpy,而不是memcpystrncpy

+0

OP询问了一个'strncpy()'比较。 – chux

+0

非常真实,我发现使用大字符串,我已经很好地知道其他地方的长度。 – JavaProphet

+0

我个人不会推荐'strcpy',因为它可能容易受到缓冲区溢出攻击。 – Taywee

相关问题