我如何为2D阵列分配内存?

Nir*_*van 4 c++ arrays new-operator dynamic-arrays

如何使用'new'运算符声明二维数组?我的书说:

int (*p)[4];
p=new[3][4];
Run Code Online (Sandbox Code Playgroud)

但这对我没有意义.p是一个指向4个整数数组的指针,那怎么能指向一个二维数组呢?

Mir*_*res 8

看来你需要指向指针的指针.编辑:嗯,更确切地说,以下示例创建一个指向数组的指针数组.

先做:

int **p = new int*[NUM];
Run Code Online (Sandbox Code Playgroud)

在这里你已经创建了一系列指针.现在,您需要为每个数组创建另一个数组.你可以这样做:

for(int i = 0; i < NUM; i++)
{
    p[i] = new int[ANOTHER_NUM];
}
Run Code Online (Sandbox Code Playgroud)

对于释放,你做的类似,但反过来:

for(int i = 0; i < NUM; i++)
{
    delete[] p[i];
}
Run Code Online (Sandbox Code Playgroud)

最后:

delete[] p;
Run Code Online (Sandbox Code Playgroud)

现在你可以使用它了.这样你就可以创建N维数组,只需添加更多'*'.如果您有任何其他特殊问题,请在评论中提问.

但是,一般来说,对于进一步的信息,我建议你首先尝试使用"C++中的2D数组"或"2D数组C++的动态分配"等问题,即此查询.


Mik*_*one 5

其他答案包括为您的行设置一个指针int数组,每行都有一个指向数组的指针。另一种选择是简单地分配一个足够大的一维数组来容纳所有二维数组的元素:

int* p = new int [3 * 4];
Run Code Online (Sandbox Code Playgroud)

然后不使用p[r][c]语法,而是使用p[r * kNumCols + c]. 在这个例子中,kNumCols = 4. 这通常是在 LAPACK 风格的数字处理中所做的,因为它使内存中的事物保持连续,并且您不需要分配这么多内存块。

注意:这在实践中通常不会比替代方案慢,因为行偏移计算被公共子表达式优化移出循环。此外,许多优化器都知道寻找这种模式。此外,通过将您的数据保存在单个内存块中,数据更有可能留在缓存中。

在 C++ 中,您可以p[][]使用辅助模板类来实现表示法:

template<class T>
class Array2DPtrRow
{public:
    Row(T* row_): row(row_) {}
    operator T*() { return row; }
    T& operator [](size_t c) { return row[c]; }
private:
    T* row;
};

template<class T, size_t NC>
class Array2DPtr
{public:
    Array2DPtr(T* buf_): buf(buf_) {}
    operator T*() { return buf; }
    Array2DPtrRow<T> operator [](size_t r)
        { return Array2DPtrRow<T>(buf + NC * r); }
private:
    T* buf;
};
Run Code Online (Sandbox Code Playgroud)

这将优化为与上面相同的代码,但允许您使用[][]符号并要求您在编译时知道您的数组维度。用法示例:

Array2DPtr<int, 4> p(new int[3 * 4]);
p[1][2];
Run Code Online (Sandbox Code Playgroud)

这可以转换为使 NC 成为类成员而不是模板参数,但最终对象不再只是一个指针:

template<class T>
class Array2DPtr
{public:
    Array2DPtr(T* buf_, size_t nc_): buf(buf_), nc(nc_) {}
    operator T*() { return buf; }
    Array2DPtrRow<T> operator [](size_t r)
        { return Array2DPtrRow<T>(buf + nc * r); }
private:
    T* buf;
    size_t nc;
};

Array2DPtr<int> p(new int[3 * 4], 4);
p[1][2];
Run Code Online (Sandbox Code Playgroud)

请注意,这些类都不需要复制构造函数、赋值运算符或析构函数,因为它们不像常规指针那样拥有指向内存的所有权。所以要释放内存,你还需要做:

delete[] p;
Run Code Online (Sandbox Code Playgroud)

或者,如果您的编译器无法弄清楚:

delete[] (int*)p;
Run Code Online (Sandbox Code Playgroud)


小智 1

你需要这样的东西

int **array_ptr; //two * are needed because it is a pointer to a pointer

array_ptr=new int*[firstnumber]; //creates a new array of pointers to int objects

for(int i=0; i<firstnumber; ++i)
array_ptr[i]=new int[secondnumber];
Run Code Online (Sandbox Code Playgroud)