如何在c ++中访问动态分配的矩阵?

时间:2013-12-27 11:43:12

标签: c++ arrays oop memory-management matrix

我已经创建了一个类对象的动态矩阵,但是我在处理返回的指针时犯了很大的麻烦。

我的目的是创建一个Point(Int x,Int y)类的矩阵,然后在程序中以不同的方式使用它。 一切正常,但我无法弄清楚功能之间的返回指针游戏。

class Point
{
   private:
     int x; 
     int y;
   public:
     Point(int x,int y);
     void SetPoint(int x,int y);

};

在第二个类中,我使用Point对象作为类成员。

Init_Pallet()用于初始化矩阵。

class Warehouse
{
   private:
       Robot r1,r2;
       Point *Pallet_Matrix;

   public:
       Point* Init_Pallet();
};

这是Init函数

Point* Warehouse::Init_Pallet()
{

    int rows =10,cols =10;
    Point** Pallet_Matrix = new Point*[rows];
    for (int i = 0; i < rows; i++)
        Pallet_Matrix[i] = new Point[cols];
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; j++)     //Pallet matrix Init, x point for robots amount in position and y for box amount
            Pallet_Matrix[i][j].SetPoint(0,0);
    return *Pallet_Matrix;
}

初始化函数由WareHouse C'Tor调用(忽略其他变量)

Warehouse::Warehouse(Robot p_r1,Robot p_r2): r1(p_r1),r2(p_r2)
{
    this->r1=p_r1;
    this->r2=p_r2;
    Point *p =Init_Pallet();
    this->Pallet_Matrix=p;
}

我的问题是:如何将地址从Init函数返回到矩阵的开头到调用它的C'Tor? 第二个问题:在将矩阵地址返回给C'Tor后,如何以Matrix [i] [j]的格式访问矩阵的不同位置。

提前感谢您的所有帮助和时间。

4 个答案:

答案 0 :(得分:2)

您应该Init_Pallet返回Point**,然后return Pallet_Matrix;。目前,您正在复制您从函数中分配的Point*之一,因此该副本不再是您可以索引的连续数组的一部分。

不要忘记析构函数中的delete[]动态数组。

但是,您更应该使用标准库容器,例如std::arraystd::vector。然后你不需要担心自己的动态分配,也不需要指责乱搞。

如果我这样做,我只会:

class Warehouse
{
   public:
       Warehouse() : Pallet_Matrix() { }
   private:
       Robot r1,r2;
       std::array<std::array<Point, 10>, 10> Pallet_Matrix;
};

就是这样。不需要init。没有动态分配。不为每个元素指定0(如果给Point一个零初始化的默认构造函数)。完成。

答案 1 :(得分:2)

如何将地址从Init函数返回到矩阵的开头到C'Tor?

如果您真的只需要第一个元素的地址,那么非常简单:

return &Pallet_Matrix[0][0];

如何在返回矩阵地址后以Matrix [i] [j]的格式访问矩阵的不同位置

Init_Pallet是一个成员函数,可以直接与Pallet_Matrix成员一起使用。否则,Init_Pallet函数实际上可能会返回Point**,但这应该让您觉得此代码出了问题。


更好的 [1] 解决方案将是:

  1. 定义Point的默认构造函数:

    class Point
    {
       public:
         Point() : x(0), y(0){}
         ...
    
  2. 使用std::vector而不是动态分配的数组:

    class Warehouse
    {
       private:
           std::vector< std::vector<Point> > Pallet_Matrix;
    

    而不是:

    Point *p =Init_Pallet();
    this->Pallet_Matrix=p;
    

    你只需使用std::vector的构造函数:

    int rows = 10, cols = 10;
    Pallet_Matrix = std::vector< std::vector<Point> >(rows, cols);
    
  3. [1]更好= 您不想自己处理内存管理。

答案 2 :(得分:1)

问题是返回的Init_Pallet()类型是错误的 - 它是一行,而不是矩阵。在Warehouse::Init_Pallet()的最后一行中,您取消引用指向矩阵的正确指针,获取指向矩阵第一行的指针。

您需要在Point **Pallet_Matrix;中写Warehouse,在Point** Warehouse::Init_Pallet()的最后一行使用Init_pallet()的{​​{1}}定义和return Pallet_Matrix

符号Init_Pallet()表示Point *row是“点数组”或“指向点数组开头的指针”。符号row表示Point **matrix是“指向点数组起点的指针数组”或“指向此类数组开头的指针”。

答案 3 :(得分:0)

首先:尺寸是否真的不变,或者这只是一个 你简化了发布代码的神器?如果 它们确实是不变的,不需要动态 分配:你可以写:

Point palletMatrix[10][10];

并完成它。 (如果你有C ++ 11,那就更好了;你 可以使用std::arraypalletMatrix将拥有完整对象 语义。)

如果确实需要动态索引,那么只有合理的方式 这样做是为了编写一个简单的矩阵类,并使用它:

class Matrix
{
    int m_rows;
    int m_columns;
    std::vector<Point> m_data;
public:
    Matrix( int rows, int columns )
        : m_rows( rows )
        , m_columns( columns )
        , m_data( rows * columns, Point( 0, 0 ) )
    {
    }
    Point& operator()( int i, int j )
    {
        return m_data[ i * m_columns + j ];
    }
    //  ...
};

尝试维护表的指针表并不好 解决方案:它过于复杂,需要特殊处理 确保每行具有相同数量的列 通常表现不佳(至少在现代机器上, 其中地点很重要,乘法很便宜。

另请注意,实际数据位于std::vector。有 几乎没有new[]是一个好的解决方案的情况;如果你 你没有std::vector(而且有这样的时间) 从实施它开始,或类似的东西。 (和 std::vector也不使用new[]。)

编辑:

另一件事:如果你将Point放在矩阵中,你可能会 想给它一个默认的构造函数;这通常会产生代码 简单。