for 循环条件

For-loop condition

本文关键字:条件 循环 for      更新时间:2023-10-16

由于某种原因,第二个循环中m[i][j] != 0的条件在 clion 中产生了错误EXC_BAD_ACCESS (code=1, address=0x0)。我简化了一个例子。我想订阅矢量,直到我遇到零或直到它结束。

#include <iostream>
#include <vector>
int matrixElementsSum(std::vector<std::vector<int>> m) {
for (int j = 0; j != m[0].size(); ++j) {
for (int i = 0; (m[i][j] != 0) && (i != m.size()); ++i) {
std::cout << m[i][j] << std::endl;
}
}
return 0;
}
int main() {
std::vector<std::vector<int>> matrix = { {1, 1, 1, 0} };
int s = matrixElementsSum(matrix);
std::cout << "s = " << s << std::endl;
}

在循环中:

for (int i = 0; (m[i][j] != 0) && (i != m.size()); ++i)

m[i][j] != 0将在检查大小(i != m.size()(之前执行,因此当i == m.size()时,您将越界访问,并调用未定义的行为。

要解决此类问题,您可以使用短路评估C++并像这样重写条件:

for (int i = 0; (i != m.size()) && (m[i][j] != 0); ++i)

如果达到大小 - 无论如何都会false整个条件,因此不会执行m[i][j] != 0

我认为,第一个循环中的条件应该如下所示:

j != m.size()

j != m[0].size()

它的访问很糟糕,因为您尝试通过matrixElementSums函数中的(m[i][j] != 0) && (i != m.size())访问垃圾

要解决此问题,请先添加溢出条件,而不是通过(i != m.size()) && (m[i][j] != 0)测试值条件

如果m为空,m[0].size()则具有未定义的行为。m函数调用中可能不为空,但在分析matrixElementsSum时,静态分析器无法知道调用函数的所有方式。

此外,它假设向量的向量是矩形的 - 即所有行的宽度都相同,因为您只比较第一行的大小,而不是其余部分。矩阵可能就是这种情况,但静态分析器不知道矩阵是什么。

最后,m[i][j] != 0i > m.size()时出界了。您需要先检查一下。这是最糟糕的问题,因为其他问题可以通过函数前置条件的文档来处理,而任何输入都会发生此错误。

通过使用基于范围的for循环,可以避免代码中的所有愚蠢错误,如下所示:

int matrixElementsSum(const std::vector<std::vector<int>>& m) {
for (auto const& row: m) {
for (auto const& value: row) {
std::cout << value << std::endl;
}
}
return 0;
}

少得多的混乱,更容易正确!