为什么Qt程序中未执行的多边形填充代码会导致程序崩溃?
问题原因分析
- 核心原因是栈溢出:你在Polygon函数中定义了超大局部数组
bool mask[MAXHEIGHT][MAXWIDTH],计算可得该数组占用空间为:4320 * 7680 * 1字节 = 33177600字节 ≈ 31.6MB,而macOS系统默认的用户态线程栈大小仅为8MB,远小于该数组的内存需求。 - 为什么未执行的代码也会导致崩溃:C/C++中函数内的局部非静态变量,并不是执行到变量定义的代码行才分配内存,而是在函数调用入口处,就会一次性分配整个函数栈帧需要的所有内存空间。只要你调用了Polygon函数,哪怕填充代码段的逻辑分支没有被执行,函数进入时就会尝试分配这31MB的栈空间,直接触发栈溢出崩溃,所以你加在填充段里的调试打印语句自然不会有输出。
- 额外隐藏问题:就算你修复了栈溢出问题,填充代码段还有多个逻辑漏洞:
- 遍历多边形边时,迭代器
it走到最后一个元素时,it+1会出现越界访问 - 计算
dxs时如果两个顶点y坐标相等,会触发除零错误 - Qt窗口的y轴是从上到下递增,你直接用
rect().bottom()(数值更大的y值)作为循环起点遍历,也会导致数组越界
- 遍历多边形边时,迭代器
修复方案
首先将栈上的大数组改为堆分配,推荐用vector实现:
// 替换掉原代码中的bool mask[MAXHEIGHT][MAXWIDTH]; vector<vector<bool>> mask(MAXHEIGHT, vector<bool>(MAXWIDTH, false));
更优化的方案是不需要直接分配8K分辨率的全量数组,只需要按当前窗口实际宽高分配对应大小的掩码数组即可,能大幅减少内存占用。
内容的提问来源于stack exchange,提问作者lijiabo
相关产品推荐
相关产品推荐

