在 C 中连接字符串:函数调用后字符串缓冲区没有被清除

Posted

技术标签:

【中文标题】在 C 中连接字符串:函数调用后字符串缓冲区没有被清除【英文标题】:Concatenating strings in C: string buffer is not getting cleared after function call 【发布时间】:2021-06-03 05:14:43 【问题描述】:

我试图在函数foo() 中连接两个字符串。在第一次和第二次调用foo() 之后,我希望string 的内容是abc。第一次调用后我得到的输出是abc,但第二次调用打印abcabc(第三次调用打印abcabcabc,依此类推)。字符串缓冲区没有被清除。如果有人可以分享它的内部工作原理,这将很有帮助——内存是如何分配给字符串的,以及为什么在函数的后续调用之间没有清除字符串缓冲区。

这是我使用的代码:

#include <stdio.h>
#include <string.h>

int foo()
    unsigned char string[100];
    unsigned char text[10] = "abc";
    strcat(string, text);
    printf("%s\n", string);


int main()
    foo();
    foo();
    return 0;

【问题讨论】:

没有 C 运行时。函数调用之间不清除内存。必须有人去做。在您的情况下,您可能希望 memset(string, 0, strlen(text)) 在函数的末尾。话虽如此,您可能还想使用strcpy 而不是strcat。你现在拥有它的方式string 从未初始化,所以strcat 的长度查找可以让你读取你没有权限的内存。 查看您的代码,很明显您得到的结果就是函数正在执行的操作,因为您尚未初始化 string: 调用 Undefined behaviour strcat 的文档一目了然。它要求第一个参数是 (a) 一个以空字符结尾的字符串 (b) 具有足够容量的缓冲区空间来容纳当前字符串、附录字符串、 一个以空字符结尾的字符。您的代码没有满足这些要求中的第一个,因此您调用了未定义的行为。阅读并了解您正在使用的库函数是如何工作的。 “为什么在函数的后续调用之间没有清除字符串缓冲区”:因为语言中没有任何东西声称它会被清除。如果你认为有,恐怕你被误导了。未初始化的局部变量具有 indeterminate 内容,这包括从以前的调用中看到剩余数据的可能性。 【参考方案1】:

您忘记初始化 string 变量。这就是你所有问题的原因。尝试访问未初始化变量的值会导致 Undefined behavior。

请参阅(Why) is using an uninitialized variable undefined behavior?。

#include <stdio.h>
#include <string.h>

int foo()
    unsigned char string[100] = "";
    unsigned char text[10] = "abc";
    strcat(string, text);
    printf("%s\n", string);


int main()
    foo();
    foo();
    return 0;

【讨论】:

【参考方案2】:

string 尚未初始化,因此不包含有效字符串。结果,当strcat 读取它以找到它invokes undefined behavior 的空终止符时。使用前必须先初始化

unsigned char string[100] =  0 ;

【讨论】:

以上是关于在 C 中连接字符串:函数调用后字符串缓冲区没有被清除的主要内容,如果未能解决你的问题,请参考以下文章

c语言中的getch与getchar 有啥区别?

c语言如何检测网络是不是连接

C语言中的库函数定义在啥地方啊?

c语言程序缓冲区溢出怎么办?

c语言,gets函数的详细用法?

C/C++中容易造成内存溢出的函数