vectors operator[] 返回对指定元素的引用而不进行边界检查。
这意味着它不会神奇地调整向量的大小,也不会执行任何其他操作来确保元素存在。如果元素不存在,则结果是未定义的行为——这意味着任何事情都可能发生。实际上,它经常导致程序访问无效的内存位置,从而导致崩溃。
即使对于简单的vector<int>,上述情况也是如此。通过使用 vector<vector<int> >(vector<vector<int> > 的每个元素都是 vector<int>),您的问题变得更加复杂。
您的函数实际上可能调用未定义行为的次数有点惊人。您碰巧在声明 newMatrix[i][j] = m[i][j] 时遇到了崩溃,但未定义行为的可能性实际上发生在此之前。
在外部循环中,如果m.size()(您的代码不会检查)的值为零,则m[i] 将不存在。如果m.size() 为零,这将导致m[i](如m.operator[](i))的评估具有未定义的行为。
本质上,您需要在评估m[i] 之前确保任何索引i 有效,然后还要确保j 是m[i] 的有效索引,然后再评估m[i][j]。然后对newMatrix 执行相同的操作。您的代码根本不执行此操作。更正确的函数渲染(假设意图是创建m 的副本)是
vector< vector<int> > resizeVector(vector< vector<int> > m)
{
vector< vector<int> > newMatrix;
int i,j;
newMatrix.resize(m.size()); // necessary to ensure we can access newMatrix[i] in the loop below
for (i = 0; i < m.size(); i++) // ensure i is a valid index of m
{
// newMatrix[i].size() is still zero, so we need to resize for use in the inner loop
newMatrix[i].resize(m[i].size());
for(j = 0; j < m[i].size(); j++) // ensure j is a valid index of m[i]
{
newMatrix[i][j] = m[i][j];
}
}
return (newMatrix);
}
现在,问题是,您的代码实际上是在重新创建 vector 已经提供的功能。所以,我们可以很简单地用
替换函数的主体
vector< vector<int> > resizeVector(vector< vector<int> > m)
{
vector< vector<int> > newMatrix(m);
return newMatrix;
}
甚至与
vector< vector<int> > resizeVector(vector< vector<int> > m)
{
return m;
}
这意味着你的函数(正如我修改过的)命名错误——它不会调整任何东西的大小。事实上,这是相当没有意义的,因为如果调用者这样做
x = resizeVector(y);
完全不用你的函数也能达到同样的效果,就像
x = y;
这也更有效(没有函数调用,没有创建副本以通过值传递等)。