strcat vs strncat for string literal

时间:2014-06-28 09:54:13

标签: c string compiler-construction concatenation

我想将一个字符串文字追加到目的地。我可以使用strcatstrncat

strcat(dest, "values");

或者

strncat(dest, "values", sizeof("values") - 1);

strcat代码更短,看起来很整洁。

但我想知道他们的运行时性能。

运行时strncat稍微快一点,因为不需要找到终结符吗?

或许编译器可以进行优化,所以没有区别?

3 个答案:

答案 0 :(得分:2)

首先,strcatstrncat都支持null终止符,区别在于strncat也检查复制数据的大小,并且只复制{{1} } bytes。

其次,由于n没有检查复制数据的大小,并且副本一直到达空终止符,它可能(并且会!!)导致缓冲区溢出,覆盖存储的数据在你复制到的缓冲区后的内存中。

第三,您对strncat的使用并不安全,因为您将副本限制为源缓冲区的大小,而不是目标缓冲区。例如。要正确使用它,你应该传递目标缓冲区的大小:

strcat

第四,如果源字符串的大小大于目标的strncat(dest, "values", sizeof(dest) -1 ); ,则不会追加空终止符,因此在调用n之后,您应该自己添加它:< / p>

strncat

最后一件事,因为这是strncat,它复制到目标字符串终止的地方,大小计算稍微复杂一点,实际上是:

strncat(dest, "values", sizeof(dest) -1 );
dest[sizeof(dest) - 1] = '\0';

答案 1 :(得分:1)

  1. 我绝对相信,这里的表现不是问题。
  2. 如果您查看函数strcpy()strncpy()(来自glibc)的来源,您会发现它们都需要迭代{{1}的每个字符} argument。
  3. 使用src,因为它更易于阅读和维护,并且不易出错。
  4. 此外,如果有任何可以优化此代码的东西,我想任何体面的编译器都会处理它,因为它似乎是非常常见的表达式。

答案 2 :(得分:0)

  

运行时strncat稍快,因为不需要找到终结符吗?

char *strncat(char * restrict s1, const char * restrict s2, size_t n);

不太可能。通常,char *strncat()需要在s2中找到空字符,如果它在s2[n]之前存在,则在n个字符之前停止连接。当然, 需要找到s2 strcpy(s1,s2)中的空字符

strncat(dest, "values", sizeof("values") - 1);可能而不是strcat(dest, "values");更安全

不会溢出可能截断的数组的代码:

// Assuming dest is an array
strncat(dest, "values", sizeof dest - strlen(dest) - 1);

允许优化编译器进行内部搜索&#34;众所周知的功能,如下面的功能,并发出&#34;知道&#34; &#34;值的长度/大小&#34;。这样的编译器肯定会为下面的2制作相同的性能代码,因为结果功能是相同的 - 在这种情况下。

strcat(dest, "values");
// or
strncat(dest, "values", sizeof("values") - 1);