如何使用 strncat 而不担心缓冲区溢出?

发布于 2024-11-27 09:31:03 字数 256 浏览 2 评论 0原文

我有一个缓冲区,我正在做很多 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

飘然心甜 2024-12-04 09:31:03

考虑现有字符串的大小和空终止符

#define BUFFER_SIZE 64
char buff[BUFFER_SIZE];

//Use strncpy
strncpy(buff, "String 1", BUFFER_SIZE - 1);
buff[BUFFER_SIZE - 1] = '\0';

strncat(buff, "String 2", BUFFER_SIZE - strlen(buff) - 1);

strncat(buff, "String 3", BUFFER_SIZE - strlen(buff) - 1);

Take into consideration the size of the existing string and the null terminator

#define BUFFER_SIZE 64
char buff[BUFFER_SIZE];

//Use strncpy
strncpy(buff, "String 1", BUFFER_SIZE - 1);
buff[BUFFER_SIZE - 1] = '\0';

strncat(buff, "String 2", BUFFER_SIZE - strlen(buff) - 1);

strncat(buff, "String 3", BUFFER_SIZE - strlen(buff) - 1);
じее 2024-12-04 09:31:03

为什么不使用snprintf?与 strncat 不同的是,它需要缓冲区的大小,但更重要的是,没有隐藏的 O(n)。

Strcat 需要在它连接的每个字符串上找到空终止符,并且每次都会遍历整个缓冲区以找到结尾。每当字符串变长时,strcat 就会减慢速度。另一方面,Sprintf 可以跟踪结尾。您会发现这

snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3");

通常是更快、更具可读性的解决方案。

Why not use snprintf? Unlike strncat 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

snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3");

Is frequently a faster, and more readable soluton.

陌若浮生 2024-12-04 09:31:03

在原始代码中使用 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 (note l instead of n). The strlcat function is not standard, yet it is a popular implementation-provided replacement for strncat. 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 those strlen calls (both issues present in Joe's answer), you either use an implementation-provided strlcat or implement one yourself (if your implementation provides no strlcat).

http://en.wikipedia.org/wiki/Strlcpy

慢慢从新开始 2024-12-04 09:31:03

这是最好的方法。 sizeof() 只是给你指向数据的指针的大小,如果你没有在本地分配它(在这种情况下你确实在本地分配了,但最好这样做,如果代码被重构)。

#define MAXBUFFSIZE 64

char buff[MAXBUFFSIZE];

buff[0] = 0;  // or some string

strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1);

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).

#define MAXBUFFSIZE 64

char buff[MAXBUFFSIZE];

buff[0] = 0;  // or some string

strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1);
感情洁癖 2024-12-04 09:31:03

霍根已经充分回答了这个问题;但是,如果您担心 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(...) and strncpy(...) to really make sure you stay within your buffer. If you don't have a strnlen(...) function, write it.

关于从前 2024-12-04 09:31:03

在这种情况下,我会使用 memccpy 而不是 strncat - 它更安全、更快。 (它也比 Dave 提到的 snprintf 方法更快):

/**
 * Returns the number of bytes copied (not including terminating '\0').
 * Always terminates @buf with '\0'.
 */ 
int add_strings(char *buf, int len)
{
    char *p = buf;

    if (len <= 0)
        return 0;

    p[len - 1] = '\0'; /* always terminate */

    p = memccpy(buf, "String 1", '\0', len - 1);
    if (p == NULL)
        return len - 1;

    p = memccpy(p - 1, "String 2", '\0', len - 1 - (p - buf));
    if (p == NULL)
        return len - 1;

    p = memccpy(p - 1, "String 3", '\0', len - 1 - (p - buf));

    return (p == NULL ? len : p - buf) - 1;
}

I'd use memccpy instead of strncat in this case - it's safer and much faster. (It's also faster than the approach with snprintf mentioned by Dave):

/**
 * Returns the number of bytes copied (not including terminating '\0').
 * Always terminates @buf with '\0'.
 */ 
int add_strings(char *buf, int len)
{
    char *p = buf;

    if (len <= 0)
        return 0;

    p[len - 1] = '\0'; /* always terminate */

    p = memccpy(buf, "String 1", '\0', len - 1);
    if (p == NULL)
        return len - 1;

    p = memccpy(p - 1, "String 2", '\0', len - 1 - (p - buf));
    if (p == NULL)
        return len - 1;

    p = memccpy(p - 1, "String 3", '\0', len - 1 - (p - buf));

    return (p == NULL ? len : p - buf) - 1;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文