【问题标题】:out of bound exception because for loop doesn't move to next loop/index越界异常,因为 for 循环不会移动到下一个循环/索引
【发布时间】:2021-04-16 22:58:00
【问题描述】:

我在做 leetcode 问题 289. 生命游戏 在运行我粘贴在下面的代码时,出现以下错误

第 1034 行:字符 34:运行时错误:将无符号偏移量添加到 0x608000000020 溢出到 0x608000000008 (stl_vector.h) 摘要:UndefinedBehaviorSanitizer:未定义行为 /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h :1043:34

我尝试使用打印语句来了解问题,这似乎是 for 循环适用于索引 [0] [0] 并且不移动到下一个索引。我也粘贴了下面的打印声明。如果有人可以帮助我,将非常感激

0 代表循环 i 0 代表循环 j 0输入行 0行 1col 1个 0输入行 1行 0col 1个 0输入行 -1行 0col

class Solution {
public:
    
    int countLives(vector<vector<int>>& board, int & i, int &j)
    {
        int count=0;
        vector<vector<int>> directions={{0,1},{1,0},{-1,0},{0,-1},{-1,-1},{1,1},                {-1,1},{1,-1}};
        for(int k=0;k<directions.size();k++)
        {
                int r=(i+directions[k][0]);
            cout<<i<<"input row"<<endl;
            cout<<r<<"row"<<endl;
                int c=j+directions[k][1];
            cout<<c<<"col"<<endl;
                if(r>=0 && r<board.size() && c>=0 && c<board[0].size() && board[r][c]==1|| board[r][c]==2) 
                    count++;
            cout<<count<<"count"<<endl;
            

        }
            
        return count;
    };
    
    void gameOfLife(vector<vector<int>>& board) {
        if(board.size()==0)
            return;
        for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[0].size();j++)
            {
                cout<<i<<" for loop i "<<j<<" for loop j"<<endl; 
                
                int count=countLives(board,i,j);
                if(board[i][j]==1 && count<2 || count>3)
                   board[i][j]=2;
                if(board[i][j]==0 && count==3)
                    board[i][j]=3;
            }
        }
        cout<<"done counting"<<endl;
          for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[0].size();j++)
            {
                if(board[i][j]==3)
                    board[i][j]=1;
                if(board[i][j]==2)
                    board[i][j]=0;
            }}
        
        
    }
};

【问题讨论】:

  • 按所示编译代码时出现 19 个错误。我建议添加标题。

标签: c++ for-loop indexoutofboundsexception


【解决方案1】:
if(r>=0 && r<board.size() && c>=0 && c<board[0].size() && board[r][c]==1|| board[r][c]==2) 

&amp;&amp; 运算符的优先级高于||,参见https://en.cppreference.com/w/cpp/language/operator_precedence,因此将其解析为

if( (r>=0 && ... && board[r][c]==1) || board[r][c]==2) 

因此,例如,如果r 为负数,则|| 的左侧操作数将为假,然后程序将评估右侧操作数board[r][c]==2,这当然是无效的,因为@987654329 @ 是负数。

你可能是说

if(r>=0 && r<board.size() && c>=0 && c<board[0].size() && (board[r][c]==1 || board[r][c]==2)) 

并且您可能还想将它分成几行以使其更具可读性。这可能使错误更容易被发现。

作为一般规则,无论何时在表达式中混合&amp;&amp; 和||,始终使用显式括号而不是依赖于运算符优先级。 (阅读您的代码的人也可能会发现优先级也很难记住。)

在

处也有类似的错误
if(board[i][j]==1 && count<2 || count>3)

【讨论】:

  • 您好,非常感谢您的帮助。当我在 or 语句周围加上括号时,我实际上不再有问题了,但是,我不明白,如果我在 for 循环中调用的函数中犯了与优先级相关的错误,for 循环如何防止for 循环从移动到下一个循环。
  • 我的意思是我还是不明白这个错误是怎么引起越界错误的
  • @Nnl 正如我所说,当r 是-1 时,由于这个错误,您访问board[-1][0] 这肯定是越界。 (看起来索引在内部被视为无符号,因此使用-1 会环绕并表现得像一个非常大的正索引,这也超出了范围。)我怀疑当这种情况发生时消毒剂会中止程序,这就是为什么你的for 循环不会“继续”。这是一件好事,它可以防止程序以更微妙或有害的方式(损坏数据、安全漏洞等)继续运行和失败。
  • 嗨,非常感谢您抽出宝贵时间帮助我了解您的专业知识,我从中学到了一些宝贵的东西,并衷心感谢它。我其实没有考虑-1的情况
  • @Nnl:不客气!我很高兴它有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-28
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 2016-03-19
相关资源
最近更新 更多