You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:15:30