在c ++中堆上的2D矩阵分配

时间:2011-10-07 08:26:31

标签: c++ matrix memory-management heap

我正在寻找一种在堆上分配2D(m x n)矩阵的方法,其中元素在内存中连续。目前我知道有两种方法可以实现这一目标:

第一种方法

int* M = new int[m * n];
  • Pro:M的大小可以动态确定。
  • Con:M的索引有点痛苦。 (M[i * m + j]

第二种方法

typedef int dim[2];
dim* M = new dim[n];
  • 专业:M的索引正是我想要的。
  • Con:无法动态设置第一个维度(m)的大小。

问题

有没有办法在堆上动态分配2D矩阵,我可以用[i][j] 索引元素,内存分配是连续的?

我知道使用一个类很有意义,但我特意寻找上述方法。

7 个答案:

答案 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}}

编辑:使用g ++

执行此操作的方法

这来自以下评论:

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)

使用提升arraymatrix或STL vector

您的矩阵还有一件事:Why shouldn't my Matrix class's interface look like an array-of-array?