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

使用栈分配大数组出现段错误但堆分配正常的原因是什么?

两种内存分配方式的差异核心是分配位置不同,受不同的大小规则限制:

  1. 栈上分配的变长数组触发栈溢出
    你写的long arr[n + 1]属于C99标准引入的变长数组(VLA),这类数组的内存是分配在进程的栈空间上的。
    操作系统对每个进程的栈空间设置了固定的容量上限:主流Linux发行版默认栈大小为8MB,Windows系统默认栈大小仅为1MB。当n取10^7时,单个long类型占8字节,数组总大小约为76MB,远超过栈的默认容量限制,触发栈溢出,最终导致段错误。

  2. 堆上分配的malloc不受栈容量限制
    你注释中用malloc分配的内存是位于进程的堆空间的。堆空间没有预设的固定大小上限,会根据程序的分配需求动态向操作系统申请可用内存,只要系统当前剩余内存足够支撑你的分配需求,就能分配成功,因此替换为malloc后程序运行正常。

关于内存布局的误解澄清

你看到的内存分布示意图是虚拟地址空间的逻辑布局,栈和堆确实是在同一个虚拟地址空间内相向增长,但这不代表栈可以无限制向堆方向扩展。操作系统会给每个进程的栈设置严格的最大使用阈值,一旦栈的实际用量超过这个阈值,内核会直接抛出段错误终止进程,不会允许栈占用堆的地址空间。

你可以在Linux系统下通过ulimit -s命令查看当前系统的默认栈大小,也可以通过该命令临时调整栈大小上限,但生产环境不推荐这么做,大内存分配优先使用堆内存是通用最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:24:02