Leetcode 733.Flood Fill 代码堆缓冲区溢出错误无法定位
问题:LeetCode 733 Flood Fill 堆缓冲区溢出错误定位
做LeetCode 733 Flood Fill题目时提交的C++代码触发堆缓冲区溢出,无法定位错误。
- 触发报错的测试用例:
[[0,0,0],[0,0,0]] sr = 0, sc = 0, color = 0
- 提交的原始代码:
class Solution { public: int visited[50][50]={0}; vector<vector<int>> helper(vector<vector<int>>& image, int sr, int sc, int color, int c) { int n = image.size(); int m = image[0].size(); image[sc][sr] = color; visited[sr][sc] = 1; if(sr>0 and visited[sr-1][sc] == 0 and image[sr-1][sc]==c){ helper(image, sr-1, sc, color, c); } if(sc>0 and visited[sr][sc-1] ==0 and image[sr][sc-1]==c){ helper(image, sr, sc-1, color, c); } if(sc<m-1 and visited[sr][sc+1] ==0 and image[sr][sc+1]==c){ helper(image, sr, sc+1, color, c); } if(sr<n-1 and visited[sr+1][sc]==0 and image[sr+1][sc]==c){ helper(image, sr+1, sc, color, c); } return image; } vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) { int n = image.size(); int m = image[0].size(); return helper(image, sr, sc, color, image[sr][sc]); } };
- 报错核心信息:AddressSanitizer检测到heap-buffer-overflow(堆缓冲区溢出)
错误原因定位
一共两个核心问题,直接触发溢出和逻辑错误:
行列索引写反,直接触发越界
二维vectorimage的访问规则是image[行索引][列索引],其中sr是起始行坐标、sc是起始列坐标,但你在helper函数第一行赋值时写的是image[sc][sr] = color;,把列索引当成行索引用了。
报错测试用例是2行3列的矩阵:n=2(行合法取值范围0~1),m=3(列合法取值范围0~2),当递归到sc=2时,访问image[2][sr]就会超出仅有的2行内存范围,直接触发堆缓冲区溢出。其余位置的image访问都是正确的image[sr][sc]格式,只有这一处写反。visited数组存在设计缺陷,且缺少边界判断
你把visited数组定义为类成员变量,OJ判题时会复用同一个Solution实例运行所有测试用例,上一个用例写入的visited标记不会重置,会导致后续用例的访问判断逻辑错误。另外本题不需要额外的visited数组:只要判断当前格子的颜色是否等于初始原色c即可,已经被染成目标色的格子颜色不等于c,自然不会重复递归,还能省掉额外数组空间。
额外注意:当目标颜色color和初始原色c相等时,不需要做任何处理直接返回即可,否则会出现无限递归。
修正后的可运行代码
class Solution { public: void dfs(vector<vector<int>>& image, int sr, int sc, int color, int originColor) { int n = image.size(); int m = image[0].size(); // 越界或者当前格子不是原色,直接返回 if(sr < 0 || sr >= n || sc <0 || sc >= m || image[sr][sc] != originColor) { return; } // 染色 image[sr][sc] = color; // 递归四个方向 dfs(image, sr-1, sc, color, originColor); dfs(image, sr+1, sc, color, originColor); dfs(image, sr, sc-1, color, originColor); dfs(image, sr, sc+1, color, originColor); } vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) { int originColor = image[sr][sc]; // 原色和目标色相同直接返回,避免无限递归 if(originColor == color) return image; dfs(image, sr, sc, color, originColor); return image; } };
内容的提问来源于stack exchange,提问作者Saniaaa
相关产品推荐
相关产品推荐

