如何在c++中访问动态分配的矩阵
How to access a dynamically allocated matrix in c++?
我已经创建了一个类对象的动态矩阵,但我在处理返回的指针方面做得一团糟。
我的意图是创建一个类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_Ballet()用于初始化矩阵。
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;
}
Init函数由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后,如何访问矩阵[i][j]格式的不同位置。
提前感谢您的帮助和时间。
您应该只让Init_Pallet
返回一个Point**
,然后执行return Pallet_Matrix;
。目前,您正在复制从函数中分配的一个Point*
,因此该副本不再是可以索引的连续数组的一部分。
不要忘记在析构函数中delete[]
动态数组。
但是,您应该更喜欢使用标准库容器,如std::array
或std::vector
。然后,您就不必担心动态分配,也不必担心指针会陷入混乱。
如果我这样做的话,我只会有:
class Warehouse
{
public:
Warehouse() : Pallet_Matrix() { }
private:
Robot r1,r2;
std::array<std::array<Point, 10>, 10> Pallet_Matrix;
};
就这样,不需要init
。没有动态分配。不为每个元素分配0(如果您给Point
一个默认的构造函数,该构造函数初始化为零)。完成。
如何将地址从Init函数返回到C'Tor的矩阵开头
如果您真的只需要第一个元素的地址,那么非常简单的方法是:
return &Pallet_Matrix[0][0];
返回矩阵地址后,我如何访问矩阵[i][j]格式的矩阵不同位置
Init_Pallet
是一个成员函数,它可以简单地直接与Pallet_Matrix
成员一起工作。否则,Init_Pallet
函数实际上可能会返回Point**
,但这会让您觉得此代码有问题。
更好的[1]解决方案是:
定义
Point
:的默认构造函数class Point { public: Point() : x(0), y(0){} ...
使用
std::vector
s而不是动态分配的阵列: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);
[1]Better=您不想自己处理内存管理
问题是返回的Init_Pallet()
类型错误——它是一行,而不是矩阵。在Warehouse::Init_Pallet()
的最后一行,您可以取消引用矩阵的正确指针,从而获得矩阵第一行的指针。
您需要在Warehouse
中写入Point **Pallet_Matrix;
,使用Init_pallet()
的Point** Warehouse::Init_Pallet()
定义,并在Init_Pallet()
的最后一行中使用return Pallet_Matrix
。
符号Point *row
表示row
是"点的数组"或"指向点数组开头的指针"。符号Point **matrix
表示matrix
是"指向点数组开头的指针数组"或"指向此类数组开头的指示器"。
首先:维度真的是常数吗,还是这只是一个你简化了发布代码的假象?如果它们确实是恒定的,不需要动态分配:你可以写:
Point palletMatrix[10][10];
(如果你有C++11,那就更好了;你可以使用std::array
,并且palletMatrix
将具有完整对象语义。)
如果您确实需要动态索引这样做就是编写一个简单的矩阵类,并使用它:
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
中。有实际上没有CCD_ 32是好的解决方案的情况;如果你如果没有std::vector
(而且有一段时间),你会从实现它或类似的东西开始。(以及std::vector
也不使用new[]
。)
编辑:
还有一件事:如果你把Point
放在矩阵中,你可能希望给它一个默认构造函数;这通常会使代码更简单。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 在c++中使用动态分配的问题
- 使用递归模板动态分配的多维数组
- 对具有动态分配的内存和析构函数的类对象的引用
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 访问动态分配列表中的元素
- 为什么 std::equal_to会导致动态分配?
- 调用析构函数以释放动态分配的内存
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 将静态字符数组中的字符分配给动态分配的字符数组 - 访问冲突
- 为什么在 C++ 执行删除操作后仍可以访问释放的动态分配的内存
- 在动态分配矩阵上的访问违规读数位置
- 动态分配和随机访问:Raw、Smart、Deque、Vector.为什么生得这么快,而deque却这么慢
- 尝试使用成员函数访问动态分配的成员变量时读取访问冲突
- 如何在c++中访问动态分配的矩阵
- 循环访问映射并删除动态分配的元素
- 动态分配内存时发生访问冲突
- 从 C++ 结构中包含的指针数组动态分配和访问内存
- 引用变量可以访问动态分配的内存