我正在寻找一种在堆上分配2D(m x n)矩阵的方法,其中元素在内存中连续。目前我知道有两种方法可以实现这一目标:
int* M = new int[m * n];
M
的大小可以动态确定。M
的索引有点痛苦。 (M[i * m + j]
)typedef int dim[2];
dim* M = new dim[n];
M
的索引正是我想要的。有没有办法在堆上动态分配2D矩阵,我可以用[i][j]
和索引元素,内存分配是连续的?
我知道使用一个类很有意义,但我特意寻找上述方法。
答案 0 :(得分:3)
你可以试试这个
int** M = new int*[m];
int *M_data = new int[m*n];
for(int i=0; i< m; ++i)
{
M[i] = M_data + i * n;
}
答案 1 :(得分:3)
以下是我在评论中提到的IntArray2D
课程的最低版本:
class IntArray2D
{
std::vector<int> data_;
int height_;
int width_;
public:
IntArray2D(int height, int width)
: data_(height * width), height_(height), width_(width)
{
}
int* operator[](int index)
{
return &data_[index * width_];
}
const int* operator[](int index) const
{
return &data_[index * width_];
}
};
使用示例:
IntArray2D test(100, 10);
test[99][9] = 42;
int i = test[0][0];
您可能希望添加边界检查,并且要在两个维度中执行此操作,您需要返回适当的代理对象而不是指针。练习留给读者; - )
答案 2 :(得分:2)
注意:请参阅下面的编辑了解相关操作方法。我会保留原来的帖子。
要使两个尺寸都是动态的并且元素是连续的,除了第一种方法之外别无他法。 (注意:请参阅编辑,有办法实现,但使用g ++)
这样想:当你告诉编译器计算array [i] [j]时,它会自动将它转换为:
*(array+i*m+j)
如果数组是静态的并且m
(列数)已知。或者,如果数组是2D(类型为type **
):
*(*(array+i)+j)
第二种情况是如何使用2D数组正常进行,但数据不是连续的。这让你有了第一个选择。现在在第一个选项中,在编译时,编译器必须知道 m
。如果您希望在运行时设置m
,则编译器无法计算i*m+j
。
现在有办法解决这个问题。一个是你提到的类的使用,它绕过array = new type[n*m];
并正确地重载[]
运算符。另一种方法,需要更多的内存(因此我个人不建议)是采用第二个type **
类型的数组,而不是将每个元素设置为new type[m]
,你设置它到你的一维数组中的行的开头。
尽管如此,最重要的是,必须某处<{1}}
这来自以下评论:
new type[n*m]
然后你可以使用数组,元素是连续的。
我也尝试了这个,并且它起作用了
type *array_helper = new type[n*m];
type (*array)[m] = (type (*)[m])array_helper;
我打印了地址,专门检查了type array[n][m];
和array[i][m-1]
,地址是连续的。
答案 3 :(得分:1)
你想要一个指向(int-array)的指针:
cin >> w >> h;
int (*data)[w] = (int (*)[w])new int[w*h];
for(int y=0;y<h;y++)
for(int x=0;x<w;x++)
data[y][x] = (w*y)+x;
答案 4 :(得分:1)
建立一个crazyjul的答案你只需要一次内存分配即可。
int **arr = new int*[col*(row+1)];
for(int a=0; c<col; ++a){
arr[a] = (int*)&arr[(a+1)*row];
}
答案 5 :(得分:0)
类似C的伪代码:
int** M = new int*[m];
for(int i in 0..m-1) {
M[i] = new int[n];
}
答案 6 :(得分:0)