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

使用fgets()触发AddressSanitiser: SEGV on unknown address问题求助

分析fgets()触发SEGV on unknown address的原因及修复方案

嘿,我太懂这种从scanf转fgets突然炸段错误的憋屈了!咱们来一步步拆解问题,找到根因和修复办法:

最可能触发SEGV的几个坑

1. 给fgets传了野指针/未初始化指针

这是90%概率会碰到的问题!举个反例:

char *buf; // 这里buf是未初始化的野指针,指向随机内存
fgets(buf, 100, stdin); // 往随机内存写,直接触发段错误

之前用scanf的时候如果也是用这个野指针,其实已经是未定义行为了——只是运气好没触发崩溃而已。而fgets一写就炸,只是刚好撞上了非法内存区域。

正确的做法是用已分配的可写内存:

  • 要么用栈上的固定数组(简单安全,推荐):char buf[256];
  • 要么用堆分配的指针(适合动态大小):char *buf = malloc(256);(记得用完free)

2. 传递了只读内存的指针给fgets

比如你用字符串字面量当缓冲区:

char *buf = "hello world"; // 字符串字面量存在只读数据段
fgets(buf, 20, stdin); // 尝试写入只读内存,直接炸SEGV

这种情况scanf往这里写也会炸,只是你之前的scanf用法没碰这块内存而已。

3. 缓冲区大小参数异常(少见)

如果给fgets传的大小是0或者负数,虽然C标准规定fgets会返回NULL,但某些平台下可能触发段错误——不过这种情况比前两种少见多了。


针对你的场景的修复代码

结合你说的“之前scanf正常,换fgets就炸”,大概率是指针/缓冲区的问题,给你一个安全的示例框架:

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

int main(void) {
    int x = -1;
    // 用栈上的固定大小数组当缓冲区(按需调整大小,留足空间存换行符)
    char input_buf[256];

    // !重要:处理之前scanf留下的换行符
    // 如果你之前用了scanf("%d", &x); 输入完数字按回车,换行符会留在输入缓冲区
    // 这时候fgets会先读这个换行符,导致你以为输入没生效(虽然不会炸,但逻辑不对)
    int c;
    while ((c = getchar()) != '\n' && c != EOF);

    // 安全调用fgets:检查返回值,确保读取成功
    if (fgets(input_buf, sizeof(input_buf), stdin) != NULL) {
        // 可选:去掉fgets读取的换行符(如果不需要保留)
        input_buf[strcspn(input_buf, "\n")] = '\0';
        // 接下来处理输入内容
        printf("你输入的内容:%s\n", input_buf);
    } else {
        fprintf(stderr, "读取输入失败\n");
        return 1;
    }

    // 如果你需要动态大小的缓冲区,用堆分配:
    // char *dyn_buf = malloc(256);
    // if (dyn_buf == NULL) {
    //     fprintf(stderr, "内存分配失败\n");
    //     return 1;
    // }
    // fgets(dyn_buf, 256, stdin);
    // // 处理内容...
    // free(dyn_buf); // 务必释放内存

    return 0;
}

额外提醒

  • 永远确保fgets的第一个参数是可写的、已分配的有效内存,大小参数要和缓冲区实际大小一致(用sizeof数组是最安全的,堆分配的话要自己跟踪大小)。
  • 从scanf转fgets时,一定要清空之前scanf留下的换行符——这虽然不会导致SEGV,但会让程序逻辑不符合预期,很多人会误以为是fgets的问题。

内容的提问来源于stack exchange,提问作者FatimahFatCakes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:05:05