无法找到未定义行为的原因



在下面的程序中,我声明了一个全局变量(adj_matrix(,以便在不同的函数中使用它。它在另一个函数(init_matrix(中定义。

我使用测试用例3 1 2测试了该程序,并收到了分段错误。

3 1 2
YES
Segmentation fault: 11

令人惊讶的是,当我取消注释construct_matrix函数中的cout行时,分段错误消失了。

对我来说,这看起来像是未定义行为的情况,但我无法弄清楚它发生的原因和地点。请帮忙。

以下是程序:

#include <iostream>
#include <vector>
using namespace std;
vector<vector<int> > adj_matrix;
void init_matrix(int size, int val)
{
adj_matrix.reserve(size);
for (int i = 0; i < size; ++i)
{
adj_matrix[i].reserve(size);
for (int j = 0; j < size; ++j)
{
if(i == j)
adj_matrix[i][i] = 0;
else
adj_matrix[i][j] = val;
}
}
}
void construct_matrix(int size, int k, int val)
{
// k denotes how many components we want
for (int i = k - 1; i < size - 1; ++i)
{
adj_matrix[i][i + 1] = val;
adj_matrix[i + 1][i] = val;
// Uncommenting the following line resolves the seg-fault error
// cout << i << endl;
}
}
void print_matrix(int size)
{
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
cout << adj_matrix[i][j];
cout << endl;
}
}
int main()
{
int n, a, b;
cin >> n >> a >> b;
/*
The solution uses the fact that atleast one of G or G complement is always connected.
In cases where we have to show both are connected (not possible when n is 2 or 3), 
we draw a simple graph connected v1 v2 v3...vn. The complement will be also connected (n != 2 and 3)
*/
if(a == 1 && b == 1)
{
if(n == 2 || n == 3)
cout << "NO" << endl;
else
{
cout << "YES" << endl;
init_matrix(n, 0);
construct_matrix(n, 1, 1);
print_matrix(n);
}
}
else if(a == 1)
{
cout << "YES" << endl;
init_matrix(n, 1);
construct_matrix(n, b, 0);
print_matrix(n);
}
else if(b == 1)
{
cout << "YES" << endl;
init_matrix(n, 0);
construct_matrix(n, a, 1);
print_matrix(n);
}
else
cout << "NO" << endl;
return 0;
}

对于对问题感兴趣的人,这是一个解决方案,请访问此处。

PS:我已经检查了函数中for循环中的边界,它们是正确的。如果不是这种情况,无论cout行如何,程序都将抛出分段错误。

此代码中未定义行为的原因/原因之一是使用operator[]访问尚未创建的 vector 元素。

从 http://www.cplusplus.com/reference/vector/vector/operator[]/:

类似的成员函数 vector::at 与此运算符函数具有相同的行为,不同之处在于 vector::at 经过边界检查,并通过抛出out_of_range异常来发出请求的位置超出范围的信号。

可移植程序不应使用超出范围的参数 n 调用此函数,因为这会导致未定义的行为。

reserve不会创建矢量的新元素。它只是确保向量为它们分配了足够的内存。如果要创建可以访问的新元素,请使用resize。(https://stackoverflow.com/a/7397862/3052438(

我还建议在解决第一个问题后,仔细检查所有向量访问是否存在越界索引。

adj_matrix.reserve(size);不创建任何元素,而只保留向量的大小。 因此adj_matrix[i].reserve(size);i大于adj_matrix.size()时,这是未定义的行为

相关内容

  • 没有找到相关文章

最新更新