[英]strcat vs strncat for string literal
I want to append a string literal to destination. 我想将字符串文字附加到目标。 I can use
strcat
or strncat
: 我可以使用
strcat
或strncat
:
strcat(dest, "values");
Or 要么
strncat(dest, "values", sizeof("values") - 1);
strcat
has shorter code, it looks neat. strcat
代码较短,看起来很整洁。
But I wonder about their runtime performance. 但是我想知道它们的运行时性能。
Is strncat
slightly faster at runtime because there's no need to locate terminator? 因为不需要定位终止符,
strncat
在运行时是否会稍微快一些?
Or maybe compilers could do optimization and so there is no difference? 也许编译器可以进行优化,所以没有区别吗?
First, both strcat
and strncat
loks for the null terminator, the difference is that strncat
also check for the size of the copied data, and will copy only n
bytes. 首先,
strcat
和strncat
查找空终止符,不同之处在于strncat
还检查复制数据的大小,并且仅复制n
个字节。
Second, since strcat
does not check for the size of the copied data, and copies until it gets to a null terminator, it might (and will!!) cause a buffer overflow, overriding data that is stored in memory after the buffer you copy to. 其次,由于
strcat
不会检查复制数据的大小,而是一直复制到空终止符,因此可能(并且将!!)导致缓冲区溢出,从而覆盖复制缓冲区之后存储在内存中的数据至。
Third, your usage of the strncat is not safer, as you limit the copy by the size of the source buffer, not the destination buffer. 第三,对strncat的使用并不安全,因为您将复制限制为源缓冲区而不是目标缓冲区的大小。 Eg to use it correctly you should pass the size of the destination buffer:
例如,要正确使用它,您应该传递目标缓冲区的大小:
strncat(dest, "values", sizeof(dest) -1 );
Fourth, if the size of the source string is bigger than than n
of the destination, a null terminator will not be appended, so after the call to strncat
you should add it yourself: 第四,如果源字符串的大小大于目标的
n
,则不会附加空终止符,因此在对strncat
的调用之后,您应该自己添加它:
strncat(dest, "values", sizeof(dest) -1 );
dest[sizeof(dest) - 1] = '\0';
Last thing, since this is strncat, and it copies to wherever the destination string terminates, the size calculation is slightly more complex and is actually: 最后一件事,因为这是strncat,并且它将复制到目标字符串终止的任何地方,所以大小计算稍微复杂一些,实际上是:
strncat(dest, "values", total_size_of_dest_buffer - strlen(dest) - 1 );
strcpy()
and strncpy()
(from glibc) you'll find out that both of them need to iterate over each character of src
argument. strcpy()
和strncpy()
这两个函数的源代码(来自glibc),您会发现它们都需要遍历src
参数的每个字符。 strcpy()
as it's much easier to read and maintain, and is less error-prone. strcpy()
可以更轻松地读取和维护它,并且不易出错。 Also, if there is anything that could optimize this code, I guess any decent compiler will handle that, as it seems to be quite common expression. 另外,如果有什么可以优化此代码的,我想任何不错的编译器都可以处理,因为这似乎很常见。
Is
strncat
slightly faster at runtime because there's no need to locate terminator?因为不需要定位终止符,
strncat
在运行时是否会稍微快一些?
char *strncat(char * restrict s1, const char * restrict s2, size_t n);
Unlikely. 不太可能。 In general,
char *strncat()
needs to locate a null character in s2
, if it exists before s2[n]
, as concatenation stop before n
characters. 通常,如果
char *strncat()
在s2[n]
之前存在,则需要在s2
定位一个空字符 ,因为串联终止在n
字符之前。 Of course, the null character in s2
of strcpy(s1,s2)
needs to be found. 当然,需要找到
strcpy(s1,s2)
s2
中的空字符 。
strncat(dest, "values", sizeof("values") - 1);
may be slower than strcat(dest, "values");
可能比
strcat(dest, "values");
慢 strcat(dest, "values");
and is not safer . 而且不安全 。
Code that does not overrun the array that may truncate: 不会超出可能会截断的数组的代码:
// Assuming dest is an array
strncat(dest, "values", sizeof dest - strlen(dest) - 1);
An optimization compiler is allowed to "look-inside" well known functions like the ones below and emit code that "knows" the length/size of "values". 优化编译器可以“查找”下面的函数,并发出“知道”“值”的长度/大小的代码。 such a compiler would certainly make equivalent performance code for the 2 below as the resultant functionality is identical - in this case.
这样的编译器肯定会为下面的2做等效的性能代码,因为最终的功能是相同的-在这种情况下。
strcat(dest, "values");
// or
strncat(dest, "values", sizeof("values") - 1);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.