如何使用 strncat 而不担心缓冲区溢出?
我有一个缓冲区,我正在做很多 strncat。我想确保我永远不会溢出缓冲区大小。
char buff[64];
strcpy(buff, "String 1");
strncat(buff, "String 2", sizeof(buff));
strncat(buff, "String 3", sizeof(buff));
我想说的是 buff - xxx,而不是 sizeof(buff)。我想确保我永远不会覆盖缓冲区
I have a buffer, I am doing lot of strncat. I want to make sure I never overflow the buffer size.
char buff[64];
strcpy(buff, "String 1");
strncat(buff, "String 2", sizeof(buff));
strncat(buff, "String 3", sizeof(buff));
Instead of sizeof(buff), I want to say something buff - xxx. I want to make sure I never override the buffer
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
考虑现有字符串的大小和空终止符
Take into consideration the size of the existing string and the null terminator
为什么不使用
snprintf
?与 strncat 不同的是,它需要缓冲区的大小,但更重要的是,没有隐藏的 O(n)。Strcat 需要在它连接的每个字符串上找到空终止符,并且每次都会遍历整个缓冲区以找到结尾。每当字符串变长时,strcat 就会减慢速度。另一方面,Sprintf 可以跟踪结尾。您会发现这
通常是更快、更具可读性的解决方案。
Why not use
snprintf
? Unlikestrncat
it expects the size of the buffer, but more importantly, there's no hidden O(n).Strcat needs to find the null-terminator on each string it concatenates, and each time run through the whole buffer to find the end. Each time the string gets longer, strcat slows down. Sprintf, on the other hand can keep track of the end. you'll find that
Is frequently a faster, and more readable soluton.
在原始代码中使用
strncat
函数的方式实际上适用于另一个函数:strlcat
(注意l
而不是n )。
strlcat
函数不是标准函数,但它是strncat
的流行实现提供的替代品。strlcat
期望整个目标缓冲区的总大小作为其最后一个参数。同时,strncat 期望目标缓冲区剩余未使用部分的大小作为其第三个参数。因此,您的原始代码不正确。
我建议您不要使用
strncpy
进行可怕的滥用,并使用那些strlen
调用进行显式重新扫描(这两个问题都出现在 Joe 的答案中),您可以使用实现提供的strlcat
或自己实现一个(如果您的实现未提供strlcat
)。http://en.wikipedia.org/wiki/Strlcpy
The way you use the
strncat
function in your orignal code would actually be appropriate for another function:strlcat
(notel
instead ofn
). Thestrlcat
function is not standard, yet it is a popular implementation-provided replacement forstrncat
.strlcat
expects the total size of the entire destination buffer as its last argument.Meanwhile,
strncat
expects the size of the remaining unused portion of the target buffer as its third argument. For this reason, your original code is incorrect.I would suggest that instead of doing that horrible abuse of
strncpy
and making explicit rescans with thosestrlen
calls (both issues present in Joe's answer), you either use an implementation-providedstrlcat
or implement one yourself (if your implementation provides nostrlcat
).http://en.wikipedia.org/wiki/Strlcpy
这是最好的方法。
sizeof()
只是给你指向数据的指针的大小,如果你没有在本地分配它(在这种情况下你确实在本地分配了,但最好这样做,如果代码被重构)。This is the best way to do it.
sizeof()
just gives you size of the pointer to the data if you don't allocate it locally (you did allocate locally in this case but better to do it this way and it will work if the code is re-factored).霍根已经充分回答了这个问题;但是,如果您担心
strcat(...)
中的缓冲区溢出,您也应该同样担心所有其他字符串函数中的缓冲区溢出。使用
strnlen(...)
和strncpy(...)
来真正确保您留在缓冲区内。如果您没有strnlen(...)
函数,请编写它。Hogan has answered the question sufficently; however, if you are worried about buffer overflows in
strcat(...)
you should equally be worried about buffer overflows in all the other string functions.Use
strnlen(...)
andstrncpy(...)
to really make sure you stay within your buffer. If you don't have astrnlen(...)
function, write it.在这种情况下,我会使用
memccpy
而不是strncat
- 它更安全、更快。 (它也比 Dave 提到的 的snprintf
方法更快):I'd use
memccpy
instead ofstrncat
in this case - it's safer and much faster. (It's also faster than the approach withsnprintf
mentioned by Dave):