jsc*_*ode 9 c string buffer-overflow
我有一个缓冲区,我正在做很多strncat.我想确保我永远不会溢出缓冲区大小.
char buff[64];
strcpy(buff, "String 1");
strncat(buff, "String 2", sizeof(buff));
strncat(buff, "String 3", sizeof(buff));
Run Code Online (Sandbox Code Playgroud)
而不是sizeof(buff),我想说一些buff - xxx.我想确保我永远不会覆盖缓冲区
Joe*_*Joe 16
考虑现有字符串和空终止符的大小
#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);
Run Code Online (Sandbox Code Playgroud)
Dav*_*ave 12
为什么不用snprintf?不像strncat它期望缓冲区的大小,但更重要的是,没有隐藏的O(n).
strcat的需要找到每串各贯穿全缓冲运行找到结束时间空终止它加到和.每次字符串变长,strcat都会变慢.另一方面,Sprintf可以跟踪结束.你会发现的
snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3");
Run Code Online (Sandbox Code Playgroud)
通常是一个更快,更易读的解决方案.
strncat在orignal代码中使用该函数的方式实际上适用于另一个函数:( strlcat注意l而不是n).该strlcat功能不是标准功能,但它是一种流行的实现提供的替代品strncat.strlcat期望整个目标缓冲区的总大小作为其最后一个参数.
同时,strncat期望目标缓冲区的剩余未使用部分的大小作为其第三个参数.因此,您的原始代码不正确.
我建议,而不是做的那个可怕的虐待strncpy,并制定与明确的重新扫描strlen调用(目前在乔的回答这两个问题),您既可以使用一个实现提供的strlcat或实现一个自己(如果您的实现不提供strlcat).
http://en.wikipedia.org/wiki/Strlcpy
这是最好的方法。 sizeof()如果您不在本地分配数据,则只会为您提供指向数据的指针的大小(在这种情况下,您确实在本地分配了数据,但最好以这种方式进行分配,并且如果代码被重构,它将起作用)。
#define MAXBUFFSIZE 64
char buff[MAXBUFFSIZE];
buff[0] = 0; // or some string
strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1);
Run Code Online (Sandbox Code Playgroud)