C语言生成指定范围int数组时malloc触发Segmentation fault问题
故障原因
有符号整数溢出
32位有符号int的取值范围为[-2147483648, 2147483647],你的代码中min和max都是int类型,计算max - min +1时,运算过程默认按int类型执行,2147483647 - (-2147483648)已经超出了有符号int的最大值,属于C标准定义的未定义行为,哪怕后续赋值给long int类型的len,也无法修正已经溢出的结果。malloc入参异常
malloc的入参类型是无符号整数size_t,32位环境下size_t的最大值为4294967295。当len=4294967296时,sizeof(int) * len的结果为17179869184,转换为32位size_t时会发生整数环绕,最终入参变为0。多数系统实现中malloc(0)会返回不可访问的无效指针,或者直接返回NULL,访问该地址就会触发段错误。
就算在64位环境下,16GB的连续内存申请也大概率会超出进程可用的地址空间限制,malloc会返回NULL,而你main函数中没有判断ft_range的返回值是否为空,直接解引用空指针自然触发崩溃。逻辑合理性问题
当min=-2147483648、max=2147483647时,循环需要执行40多亿次才能完成数组赋值,就算内存分配成功,执行时间也远超正常业务的可接受范围,本身就属于不合理的逻辑设计。
修复方案
- 计算长度前先将
min、max强制转换为long类型,避免运算过程溢出:
len = (long)max - (long)min + 1;
main函数调用ft_range后,先判断返回值是否为NULL,再执行后续的读写和释放操作。- 增加长度合法性校验,当
len超过合理阈值(例如100万)时直接返回NULL,避免申请超大内存导致系统资源耗尽。
内容的提问来源于stack exchange,提问作者Raphael Rakhimov
相关产品推荐
相关产品推荐

