问题描述
A 评论 对我的一个答案让我有点困惑.当试图计算将两个字符串连接到一个新的内存块需要多少内存时,据说使用 snprintf
优于 strlen
,如下图:
A comment on one of my answers has left me a little puzzled. When trying to compute how much memory is needed to concat two strings to a new block of memory, it was said that using snprintf
was preferred over strlen
, as shown below:
size_t length = snprintf(0, 0, "%s%s", str1, str2);
// preferred over:
size_t length = strlen(str1) + strlen(str2);
我可以在这背后得到一些推理吗?有什么优势,如果有的话,人们会看到一个结果与另一个不同吗?
Can I get some reasoning behind this? What is the advantage, if any, and would one ever see one result differ from the other?
推荐答案
是我说的,我在 写得又快又粗,让我解释一下.我的观点只是您应该使用使用相同方法来计算最终用于填充字符串的长度的模式,而不是使用两种可能存在细微差别的不同方法.
I was the one who said it, and I left out the +1
in my comment which was written quickly and carelessly, so let me explain. My point was merely that you should use the pattern of using the same method to compute the length that will eventually be used to fill the string, rather than using two different methods that could potentially differ in subtle ways.
例如,如果您有三个字符串而不是两个,并且其中两个或更多重叠,则有可能 strlen(str1)+strlen(str2)+strlen(str3)+1
超过 SIZE_MAX
并超过零,导致输出分配不足和截断(如果使用 snprintf
)或极其危险的内存损坏(如果 strcpy 和
strcat
).
For example, if you had three strings rather than two, and two or more of them overlapped, it would be possible that strlen(str1)+strlen(str2)+strlen(str3)+1
exceeds SIZE_MAX
and wraps past zero, resulting in under-allocation and truncation of the output (if snprintf
is used) or extremely dangerous memory corruption (if strcpy
and strcat
are used).
snprintf
将返回 -1
和 errno=EOVERFLOW
,所以你受到保护.不过,您确实需要在使用前检查返回值,并为空终止符添加一个.
snprintf
will return -1
with errno=EOVERFLOW
when the resulting string would be longer than INT_MAX
, so you're protected. You do need to check the return value before using it though, and add one for the null terminator.
这篇关于计算字符串长度的不同方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!