两段floodFill代码逻辑差异:为何一段出现堆缓冲区溢出?
泛洪填充代码的堆缓冲区溢出问题分析
两段实现泛洪填充的C++代码,一段存在堆缓冲区溢出风险,另一段无此问题,核心差异及问题根源如下:
存在堆缓冲区溢出的代码
void FFHelper(vector<vector<int>>& image, int i, int j, int newColor, int oldColor) { static int m = image.size(); static int n = image[0].size(); if (i < 0 || j < 0 || i >= m || j >= n || image[i][j] != oldColor) { return; } image[i][j] = newColor; FFHelper(image, i+1, j, newColor, oldColor); FFHelper(image, i-1, j, newColor, oldColor); FFHelper(image, i, j+1, newColor, oldColor); FFHelper(image, i, j-1, newColor, oldColor); } vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) { FFHelper(image, sr, sc, color, image[sr][sc]); return image; }
无缓冲区溢出的代码
void dfs(vector<vector<int>>& image, int i, int j, int val, int newColor) { if(i < 0 || i >= image.size() || j < 0 || j>= image[0].size() || image[i][j] == newColor || image[i][j] != val) { return; } image[i][j] = newColor; dfs(image, i - 1, j, val, newColor); dfs(image, i + 1, j, val, newColor); dfs(image, i, j - 1, val, newColor); dfs(image, i, j + 1, val, newColor); } vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) { int val = image[sr][sc]; dfs(image, sr, sc, val, newColor); return image; }
核心差异与问题根源
边界判断变量的生命周期问题
- 有问题的代码中,
m和n是静态局部变量,仅在FFHelper第一次调用时初始化。若后续多次调用floodFill处理不同尺寸的图像,m和n不会更新,仍使用旧尺寸值做边界判断。当图像尺寸变小后,原有的m/n会允许访问超出当前图像实际范围的索引,直接触发堆缓冲区溢出。 - 无问题的代码每次判断边界时,实时调用
image.size()和image[0].size()获取当前图像的真实尺寸,确保边界判断始终准确。
- 有问题的代码中,
递归终止条件的完整性
- 无问题的代码多了
image[i][j] == newColor的判断:当目标颜色与原颜色相同时,直接终止递归,避免无限递归和不必要的数组访问。 - 有问题的代码缺少该判断,若
newColor等于oldColor,会陷入无限递归,最终可能因栈溢出或反复越界访问数组引发堆缓冲区溢出。
- 无问题的代码多了
内容的提问来源于stack exchange,提问作者user20896951
相关产品推荐
相关产品推荐

