矢量分配崩溃

时间:2016-11-11 16:29:31

标签: c++ matrix vector error-handling indexoutofboundsexception

vector< vector<int> > resizeVector(vector< vector<int> > m)
{
    vector< vector<int> > newMatrix;
    int i,j;

    for (i = 0; i < m[i].size(); i++)
    {
        for(j = 0; j < m[j].size(); j++)
        {
            newMatrix[i][j] = m[i][j];
        }
    }
    return (newMatrix);
}

我正在制作一个程序,它将执行大量的矩阵操作,而且这部分崩溃了,我不知道为什么。我把它缩小到了界线:

newMatrix[i][j] = m[i][j];

它崩溃了,我不知道为什么。

5 个答案:

答案 0 :(得分:1)

除了@Saurav发布的内容之外,newMatrix为空,因此您无法为newMatrix[i][j]分配值。您可以通过初始化具有给定大小的向量来解决此问题:

vector< vector<int> > resizeVector(vector< vector<int> > m)
{
    vector< vector<int> > newMatrix(m.size());
    int i,j;

    for (i = 0; i < m.size(); i++)
    {
        newMatrix[i].resize(m[i].size());
        for(j = 0; j < m[i].size(); j++)
        {
            newMatrix[i][j] = m[i][j];
        }
    }
    return (newMatrix);
}

在for循环之前,我们初始化newMatrix以使m.size()内有许多空向量(由于它们的默认构造函数,向量为空)。在外部for循环的每次迭代期间,我们使用newMatrix成员函数确保resize中的每个向量都具有正确的大小。

请注意,如果您想要一个矢量副本,您只需编写:

vector< vector<int> > newMatrix(m);

答案 1 :(得分:0)

你的检查错了。相反它应该是

for (i = 0; i < m.size(); i++)        // m.size() gives the number of rows 
{
    for(j = 0; j < m[i].size(); j++)  // m[i].size() gives the number of columns in the row

答案 2 :(得分:0)

您尚未在未设置其尺寸的情况下分配到新newMatrix。它将默认为空,任何尝试分配给它将导致未定义的行为。

由于您不会传递新的尺寸,因此很难确切知道您要完成的任务。这就是为什么我没有就如何修复它提出更明确的建议。

答案 3 :(得分:0)

如果要分配向量的向量,则需要在对其进行索引之前为矩阵分配内存。所以你必须使用像

这样的东西
newMatrix.resize(size);
for (int i = 0; i < size; ++i) {
    newMatrix[i].resize(size);
}

或者您可以使用.push_back()向量方法向向量添加值而无需事先分配内存。

答案 4 :(得分:0)

vector s operator[]返回对指定元素的引用,而不进行边界检查。

这意味着它不会神奇地调整矢量大小,或执行任何其他操作以确保元素存在。如果元素不存在,则结果是未定义的行为 - 这意味着任何事情都可能发生。实际上,它经常导致程序访问无效的内存位置,从而导致崩溃。

即使对于简单的vector<int>,上述情况也是如此。您使用vector<vector<int> >vector<vector<int> >的每个元素都是vector<int>)来加剧您的问题。

你的功能实际上有点令人惊叹,它可能会调用未定义的行为。您恰好在语句newMatrix[i][j] = m[i][j]上遇到了崩溃,但在此之前实际发生了未定义行为的可能性。

在外部循环中,如果m[i](您的代码未检查)的值为零,则m.size()将不存在。如果m.size()为零,则会导致m[i](作为m.operator[](i))的评估具有未定义的行为。

基本上,在评估i之前,您需要确保任何索引m[i]有效,然后在评估{j之前确保m[i]m[i][j]的有效索引。 1}}。然后对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<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;

也更有效(没有函数调用,没有创建按值传递的副本等)。