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

Set matrix zeroes首行首列参考法实现报heap-buffer-overflow错误

矩阵置零算法堆缓冲区溢出错误排查

给定m×n整数矩阵matrix,若某元素为0,则需将其所在整行、整列全部置为0。采用第1行、第1列作为参考行/参考列的思路实现时,触发运行时错误:ERROR: AddressSanitizer: heap-buffer-overflow on address....,对应的C++实现代码如下:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int x=1, y=1, col=1,row=1;
        int m=matrix.size();
        int n=matrix[0].size();
        //for 1st row i.e considered as reference row for inner matrix
        for(int i=0;i<m;i++){
            if(matrix[i][0]==0)
                x=0;
        }
        // for 1st column i.e considered as reference column for inner matrix;
        for(int a=0;a<n;a++){
            if(matrix[0][a]==0)
                y=0;
        }
        //loop for the inner matrix
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(matrix[i][j]==0){
                    matrix[0][j]=0;
                    matrix[i][0]=0;
                }
            }
        }
        //for iterating over 1st row of the matrix to check for zeroes.
        for(int i=1;i<m;i++){
            if(matrix[0][i]==0){
                while(i<n){
                    matrix[i][col]=0;
                    col++;
                };
                break;
            }
        }
        //for iterating over 1 column of the matrix to check for zeroes
        for(int j=1;j<n;j++){
            if(matrix[j][0]==0){
                while(j<m){
                    matrix[row][j]=0;
                    row++;
                };
                break;
            }
        }
        if(x==0){
            for(int i=0;i<m;i++)
                matrix[0][i]=0;
        }
        if(y==0){
            for(int j=0;j<n;j++)
            matrix[j][0]=0;
        }
    }
};

错误原因

代码索引逻辑完全混乱,是触发堆缓冲区溢出的核心原因,具体问题如下:

  • 标记变量对应关系写反:注释标注x用来标记第一行是否有0、y标记第一列是否有0,但实际代码中x是遍历第一列得到的结果,y是遍历第一行得到的结果,后续置零逻辑完全错位。
  • 遍历参考标记时循环边界错误:遍历第一行的参考标记时,循环终止条件写为i<m(m是矩阵总行数),但第一行的有效列索引范围是0~n-1,当m大于n时,访问matrix[0][i]会直接超出数组边界。
  • 置零内层while循环逻辑错误:检测到参考位为0后,while循环只自增列/行偏移变量,不更新外层的行/列索引,会无限向同一行/列的越界内存位置写入0,直接触发堆溢出。比如处理列置零的代码块中,while(i<n)判断条件用的是行索引i,但循环内只做col++操作,i的值永远不变,既会死循环,又会随着col增大访问到矩阵外的内存。
  • 最后处理第一行、第一列置零的逻辑同样索引错位:比如x==0本应给第一列置零,代码却遍历写入matrix[0][i](第一行的位置),当m大于n时同样会越界访问。

修正方案

采用首行首列作为参考位的标准实现逻辑如下:

  1. 先用两个布尔变量分别标记第一行、第一列本身是否存在0,避免后续标记覆盖原始状态。
  2. 遍历从(1,1)坐标开始的内部矩阵,遇到0就把对应位置的首行参考位matrix[0][j]、首列参考位matrix[i][0]置0。
  3. 再次遍历内部矩阵,只要当前位置对应的首行参考位或首列参考位为0,就把当前位置置0。
  4. 最后根据第一步存储的布尔标记,单独处理第一行和第一列的置零。

修正后的可运行代码:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size();
        int n = matrix[0].size();
        bool firstRowHasZero = false, firstColHasZero = false;
        // 标记第一列是否存在0
        for(int i = 0; i < m; i++){
            if(matrix[i][0] == 0){
                firstColHasZero = true;
                break;
            }
        }
        // 标记第一行是否存在0
        for(int j = 0; j < n; j++){
            if(matrix[0][j] == 0){
                firstRowHasZero = true;
                break;
            }
        }
        // 用首行首列存储内部矩阵的置零标记
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(matrix[i][j] == 0){
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        // 根据标记给内部矩阵置零
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(matrix[i][0] == 0 || matrix[0][j] == 0){
                    matrix[i][j] = 0;
                }
            }
        }
        // 单独处理首行置零
        if(firstRowHasZero){
            for(int j = 0; j < n; j++){
                matrix[0][j] = 0;
            }
        }
        // 单独处理首列置零
        if(firstColHasZero){
            for(int i = 0; i < m; i++){
                matrix[i][0] = 0;
            }
        }
    }
};

内容的提问来源于stack exchange,提问作者sakshi jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:09:25