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

C语言get_string函数Windows正常Linux输出(null)问题咨询

问题根因

你的代码存在两处触发未定义行为的错误,Windows平台运行正常仅为编译器实现差异带来的巧合,和缓冲区溢出无关:

  • fgets传入的缓冲区类型错误
    你在get_string函数中写的char *s[MAX];是长度为1024的字符指针数组,本质是一块用来存内存地址的栈空间,不是用来存字符内容的字符数组。fgets要求第一个参数是指向可写字符内存块的char*类型指针,传入类型不匹配的指针数组首地址,写入操作的结果完全不受C标准保证。
    正确的字符缓冲区声明应为char s[MAX];,这才是能直接存储输入字符串的连续字符内存空间。
  • 返回栈上局部变量的地址
    即使修正了s的类型,s是属于get_string函数栈帧的局部变量,函数返回时对应的栈空间会被回收,后续任何函数调用(比如main函数中紧接着执行的printf)都可能覆盖这块内存的内容,返回指向这块已回收栈内存的指针同样属于未定义行为。MSVC编译时函数返回后栈内存没有被立刻改写,刚好残留了输入的内容才会出现运行正常的假象;GCC编译时栈空间回收逻辑不同,返回的指针指向的内存已被改写,最终输出(null)。
修复方式

你可以任选一种符合C语言内存管理逻辑的写法修复:

  • 由调用方管理缓冲区内存:修改get_string函数签名为char *get_string(char *prompt, char *buf, size_t buf_len),函数内部直接将输入读取到调用方传入的buf缓冲区中,最后返回buf指针即可,不需要额外分配释放内存,适合简单场景使用。
  • 函数内部分配堆内存:在get_string中调用malloc分配足够存储输入的堆内存,将输入读入这块堆空间后返回指针,需要注意调用方使用完字符串后必须手动调用free释放内存,避免内存泄漏。

注意:C语言中未定义行为的表现没有任何确定性,可能正常输出、可能乱码、可能触发段错误,具体表现和操作系统、编译器版本、编译参数强相关,绝对不能把某一平台下的偶然运行正常作为代码正确的依据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:39:27