C语言中函数再次调用后变量值异常改变问题求助
问题根源:栈内存失效与野指针
你的代码核心问题是返回了指向栈局部变量的指针,导致后续内存被覆盖:
- 函数
get_text_and_length里的char text[len];是栈上分配的局部数组,当函数执行完毕返回时,当前函数的栈帧会被销毁,这块内存会被标记为可复用状态。 - 你返回的结构体中,
text指针指向的就是这块已经失效的栈内存,这属于典型的野指针。 - 第一次调用函数后,
b.text暂时还能访问到旧栈数据(还没被新的操作覆盖),所以第一次打印b.text是正常的。 - 第二次调用
get_text_and_length时,新的函数栈帧会复用之前的栈内存区域,直接覆盖了b.text指向的内存空间,所以后续打印b.text会和a.text内容一致。
修复方案
方案1:使用堆内存分配
用malloc在堆上分配内存,栈帧销毁后堆内存不会被自动释放,记得使用完后手动free避免内存泄漏:
struct text_and_len get_text_and_length(){ int len; scanf("%d ", &len); // 多分配1字节存储字符串结束符'\0' char *text = malloc(len + 1); if (text == NULL) { // 处理内存分配失败的异常情况 return (struct text_and_len){NULL, 0}; } fgets(text, len+1, stdin); return (struct text_and_len) {text, len}; } // 调用函数的地方记得释放内存 void get_input_and_check_is_within(){ struct text_and_len b = get_text_and_length(); printf("%s \n", b.text); struct text_and_len a = get_text_and_length(); printf("%s \n", a.text); printf("%s \n", b.text); // 释放堆内存 free(b.text); free(a.text); }
方案2:由调用方提供缓冲区
让调用函数提前分配好缓冲区,避免在被调用函数内部分配局部栈内存:
struct text_and_len get_text_and_length(char *text, int max_len){ int len; scanf("%d ", &len); // 限制长度,防止缓冲区溢出 if (len > max_len - 1) { len = max_len - 1; } fgets(text, len+1, stdin); return (struct text_and_len) {text, len}; } void get_input_and_check_is_within(){ char b_buf[100]; struct text_and_len b = get_text_and_length(b_buf, sizeof(b_buf)); printf("%s \n", b.text); char a_buf[100]; struct text_and_len a = get_text_and_length(a_buf, sizeof(a_buf)); printf("%s \n", a.text); printf("%s \n", b.text); }
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

