首页IT科技c语言定义一个二维数组,并给二维数组赋值(C++ 使用 new 创建二维数组)

c语言定义一个二维数组,并给二维数组赋值(C++ 使用 new 创建二维数组)

时间2025-09-16 00:43:20分类IT科技浏览6086
导读:1. 直接创建 C++ 使用 new 创建二维数组最直接的方法就是 new T[M][N]。返回的指针类型是 T (* [N],它是指向数组的指针,可以直接使用数组下标形式访问元素。释放内存直接使用delete[]。示例代码:...

1. 直接创建

C++ 使用 new 创建二维数组最直接的方法就是 new T[M][N]                。返回的指针类型是 T (*)[N]                ,它是指向数组的指针                          ,可以直接使用数组下标形式访问元素                          。释放内存直接使用delete[]          。示例代码:

#include <iostream> class A { public: A() { std::cout << "A::A" << std::endl; } ~A() { std::cout << "A::~A" << std::endl; } int x; }; int main() { A (*p)[3] = new A[2][3]; delete[] p; }

执行结果:

A::A A::A A::A A::A A::A A::A A::~A A::~A A::~A A::~A A::~A A::~A

可以看到 A 的构造函数和析构函数正常执行            。如果觉得 T (*)[N] 繁琐          ,可以直接使用 auto p = new T[M][N]                         。三维数组甚至更高维数组都可以使用这种方法               。例如            ,三维数组使用 new T[M][N][O] 进行创建                         ,依旧使用 delete[] p 进行释放        。

为什么可以这样写?因为这种多维数组和普通的多维数组都是通过一维数组实现的                        。例如               ,int a[6][8]        ,实际上编译器会转化为 int b[6 * 8] 一维数组                   。然后每次访问二维数组 a[i][j] 相当于访问 b[i * 8 + j]    。从二维                、三维数组的转化过程中可以发现一些规律                        。

T a[M][N] --> T b[M * N], a[i][j] --> b[i * N + j] T a[M][N][O] --> T b[M * N * O], b[i][j][k] --> b[i * N * O + j * O + k]

编译器进行下标转换时                        ,并没有用到第 0 维的大小                   ,而其它维的大小都是必须的                       。这也就是为什么下面代码能正确执行。

int a[2][3]; int (*p)[3] = a;

由于多维数组本质上是一维数组    ,所以释放内存都是 delete[] p                        ,而没有奇怪的 delete[][] 语法                    。

2. 借助指针数组

还有一种方法就是先 new T*[M] 创建一个指针数组                       ,其每个元素保存每一行的首个元素的地址,再使用 new T[N] 创建每一行                           。示例代码如下:

A** p = new A*[2]; for (int i = 0; i < 2; ++i) { p[i] = new A[3]; } for (int i = 0; i < 2; ++i) { delete[] p[i]; } delete[] p;

这种方法非常繁琐                    ,首先 new T*[M] 不能写成 new (T(*)[M])                           ,因为它是指针数组而不是数组指针     。其次     ,需要对每一行调用 new T[N]                。释放内存时                ,要先使用 delete[] 释放每一行                          ,再调用 delete[] 释放数组指针                          。这几个步骤一步都不能错          ,不然就出现野指针或者内存泄漏          。这段代码我也是用 Address Sanitizer 和 Leak Sanitizer 检查一遍才写对            。

这种方法唯一的好处就是可以创建交错数组(Jagged Array)            ,也就是每一行的大小不一样                         。例如:

A **p = new A *[2]; p[0] = new A[3]; p[1] = new A[4]; for (int i = 0; i < 2; ++i) { delete[] p[i]; } delete[] p;

3. 借助 std::vector

可以用 std::vector 对上面这种方法进行包装                         ,使其更加易用               。示例代码如下:

std::vector<std::vector<int>> v{ std::vector<int>(3), std::vector<int>(4) }; std::cout << v[0].size() << " " << v[1].size() << std::endl;

这段代码创建了一个二维数组               ,第 0 行有 3 个元素        ,第 1 行有 4 个元素        。这种方法既能创建交错数组                        ,也不需要手动释放内存                        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
帝国cms怎么用(打造专业网站的首选——帝国CMS抓取) 美丽说SEO优化策略详解(如何提升美丽说店铺的曝光率及排名)