我的矩阵类在初始化时崩溃

时间:2015-11-11 20:57:38

标签: c++ arrays matrix vector

问题:程序崩溃

这是我的matrice.h:

class matrice {

public:
    matrice(int nbColumnTMP, int nbLineTMP);

    std::vector<std::vector<int>> returnArray();

    virtual ~matrice();

    void addValue(int numColumn, int numLine, int value);
    void editValue(int numColumn, int numLine, int numValue, int newValue);

private:
    std::vector<std::vector<int>>* array;
    int nbColumn;
    int nbLine;

};

和.cpp:

matrice::matrice(int nbColumnTMP, int nbLineTMP) {

    nbColumn = nbColumnTMP;
    nbLine = nbLineTMP;

    std::vector<int>* array2;

    for(int C = 0; C < nbColumn; C++)
    {
        array->push_back(*array2);//<- DONT WORK, CRASH

        for(int L = 0; L < nbLine; L++)
        {
            array[C][L].push_back(0); //Init matrix with 0 values
        }
    }
}

std::vector<std::vector<int>> matrice::returnArray()
{
    return *array;
}

matrice::~matrice()
{
    for(int C = 0; C < nbColumn; C++)
    {
        for(int L = 0; L < nbLine; L++)
        {
            for(int V = 0; V < int(array[C][L].size()); V++)
            {
                delete &array[C][L][V];
            }

            delete &array[C][L];
        }

        delete &array[C];
    }

    delete  &nbColumn;
    delete &nbLine;

    delete array;
}

void matrice::addValue(int numColumn, int numLine, int value)
{
    array[numColumn][numLine].push_back(value);
}

void matrice::editValue(int numColumn, int numLine, int numValue, int newValue)
{
    array[numColumn][numLine][numValue] = newValue;
}

经过几次测试后,我发现这会让我的程序崩溃:

array->push_back(*array2);

我是新手,所以我不确定我做得好,而且我也不知道为什么这不起作用......

我正在将这个类用于我的2D等距引擎,我想在其中加载一些坐标以便在之后轻松获得等轴测量坐标。

2 个答案:

答案 0 :(得分:2)

您遇到问题的原因是您正在使用指针成员,并尝试写入未初始化的内存。

此成员无需成为指针:

   std::vector<std::vector<int>>* array;

相反,将它作为一个对象,并在构造函数和其他函数中适当地调整它的大小:

   std::vector<std::vector<int>> array;

然后:

matrice::matrice(int nbColumnTMP, int nbLineTMP) : 
             array(nbColumnTMP, std::vector<int>(nbLineTMP))
{}

此外,不需要保留表示行数和列数的变量。使用适当的vector::size()方法。不需要nbColumnnbLine个成员变量。

使用无关的变量总是会导致路上的错误(由于没有正确更新),或者其他问题导致它们与矢量的实际大小不同步。例如,你的函数添加一个值 - 因为你似乎在创建一个参差不齐的二维向量,那些表示行数和列数的成员变量变得无用,唯一可靠的是使用std::vector<T>::size()功能。

此外,一旦执行此操作,矩阵类中就不需要析构函数。当对象超出范围时,向量将自动清理自身。

一般来说,如果你想要一个二维或三维向量,并且想要开始&#34; easy&#34;,那么只需声明一个。不要去指针路线。如果你这样做,那么它只是修复了一些语法错误(或习惯了语法),这很容易。一头扎进指针并动态分配内存将引导您进入各种不需要进入的问题。

编辑:

对于3维向量,

std::vector<std::vector<std::vector<int>>>;

或更好:

typedef std::vector<int> Int1D;
typedef std::vector<Int1D> Int2D;
typedef std::vector<Int2D> Int3D;
Int3D array;

然后:

matrice::matrice(int nPages, int nbColumnTMP, int nbLineTMP) : 
             array(nPages, Int2D(nbColumnTMP, Int1D(nbLineTMP)))
{}

答案 1 :(得分:0)

看起来你也是c ++的新手。

正如评论中提到的,您首先需要初始化数组。 更好的是根本不使用指针。

你的.h

中的

class matrice {

public:
    matrice(int nbColumnTMP, int nbLineTMP);

    const std::vector<std::vector<std::vector<int>>>& returnArray() const;


    void addValue(int numColumn, int numLine, int value);
    void editValue(int numColumn, int numLine, int numValue, int newValue);

private:
    std::vector<std::vector<std::vector<int>>> array;
};

和.cpp

matrice::matrice(int nbColumnTMP, int nbLineTMP)  {

    array.resize(nbColumnTMP);

    for(int C = 0; C < nbColumnTMP; C++)
    {
        array.push_back(std::vector<std::vector<int>>(nbLineTMP));
    }
}

const std::vector<std::vector<std::vector<int>>>& matrice::returnArray() const
{
    return array;
}

void matrice::addValue(int numColumn, int numLine, int value)
{
    array[numColumn][numLine].push_back(value);
}


void matrice::editValue(int numColumn, int numLine, int numValue, int newValue)
   {
     // you should also add boundary checks for numColumn and numLine
     std::vector<int>& element = array[numColumn][numLine];
     if( numValue >= 0 && numValue < element.size() ){
        element[numValue] = newValue;
     }
   }

有许多优秀的矩阵包可用,除非他们不支持您的需求,否则不要实施。 我过去使用Eigen,它显着降低了我们的核心矩阵操作的CPU负载。