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

C语言可变长结构体指针数组定义问题咨询

问题解答

你老师指出的问题确实存在,这段代码的隐患不止一处,具体原因如下:

  • 首先是C语言的变量声明规则限制:在目前仍被广泛兼容的C89/C90标准中,代码块内的局部变量必须全部声明在块的最开头,不能插在可执行语句(比如你写的fopen()、fscanf()这类运行时执行的操作)后面。你在执行完fscanf()给input赋值的语句之后,才声明数组m,在C89编译环境下本身就是语法错误。这种场景下编译器是在进入函数块的初始阶段就为所有局部变量分配栈空间,不会等你跑完fscanf给input赋值之后再计算数组长度,你以为代码会按“读文件给input赋值→按input值开数组”的顺序跑,但不符合声明位置规则时,编译器根本不会生成你预期的执行逻辑。
  • 其次你完全没做IO操作的错误校验:如果book.txt不存在、当前进程没有读权限,fopen()会返回空指针NULL,你直接把空指针传给fscanf()会直接触发程序崩溃。这种情况下input根本不会被写入有效值,还是栈上分配的随机垃圾值,你拿这个随机值当数组长度开栈数组,大概率直接触发栈溢出、段错误。
  • 最后是变长数组本身的兼容性和安全问题:你写的struct book_record *m[input]属于栈上变长数组(VLA),这个特性是C99才加入的,C11之后已经被改为编译器可选支持,像Windows平台默认的MSVC编译器就不支持这个特性。就算编译器支持,栈内存的大小通常只有几MB,如果你读入的input值过大,会直接撑爆栈空间导致程序崩溃,没有任何容错空间。

修正思路参考:

  1. 把局部变量声明统一放在代码块开头,保证旧标准兼容性
  2. 每次调用fopen()、fscanf()之后立刻检查返回值,操作失败就打印错误、退出程序,不要带着无效值往下执行
  3. 不要在栈上开变长数组装大批量指针,等确认input读入合法之后,用malloc()在堆上分配指针数组的内存,使用完之后统一free()释放
  4. 读入input之后最好做合法性判断,比如input不能是负数、不能超过你预设的合理上限,避免异常值搞崩程序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:30:10