C++

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

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;
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
执行结果:

A::A
A::A
A::A
A::A
A::A
A::A
A::~A
A::~A
A::~A
A::~A
A::~A
A::~A
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
可以看到 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]
1.
2.
编译器进行下标转换时,并没有用到第 0 维的大小,而其它维的大小都是必须的。这也就是为什么下面代码能正确执行。

int a[2][3];
int (*p)[3] = a;
1.
2.
由于多维数组本质上是一维数组,所以释放内存都是 ​​delete[] p​​,而没有奇怪的 ​​delete[][]​​ 语法。

  1. 借助指针数组
    还有一种方法就是先 ​​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;
1.
2.
3.
4.
5.
6.
7.
8.
9.
这种方法非常繁琐,首先 ​​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;
1.
2.
3.
4.
5.
6.
7.
8.
9.
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;
1.
2.
这段代码创建了一个二维数组,第 0 行有 3 个元素,第 1 行有 4 个元素。这种方法既能创建交错数组,也不需要手动释放内存。


收藏
评论
分享
举报

提问和评论都可以,用心的回复会被更多人看到评论
相关文章
c++ 用new创建二维数组~创建指针数组【转】
from here

c++ 动态分配二维数组 new 二维数组
#include "stdafx.h" #include using namespace std; int _tmain(int argc, _TCHAR* argv[]) { //建立一个16行5列的数组 int p = new int[16];//分配堆内存16个 int for(int i = 0;i < 16;i++)//分配堆内存给每一个int*...

C++中二维数组new小结
二维数组new小结 转自水木清华1. A (ga)[n] = new A[m][n]; ... delete []ga;缺点:n必须是已知优点:调用直观,连续储存,程序简洁(经过测试,析构函数能正确调用)2. A* ga = new A*[m]; for(int i = 0; i < m; i++) ga[i] = new A[n]; ... for(int i = 0; i < m; i++) delete []ga[i]; delete []ga;缺点:非连续储存,程序烦琐,ga为A**类型优点:调用直观,n可以不是已知3. A* ga = new A[m*n]; ...

c++动态创建二维数组
 c++动态创建二维数组方法1:用一维数组代替二维数组 int n,m; cin>>n>>m; int* a = new int[ nm]; for(int i = 0 ; i<n ; ++i) { cout<<endl; for(int j = 0 ; j<m ; ++j) { a[im+j] = i+j; cout<<a[i

c++用vector创建二维数组
1 vector二维数组的创建和初始化 std::vector <int> vec(10,90); //将10个一维动态数组初始为90std::vector<std::vector<int> > vec(row,vector<int>(col,0)); //初始化row * col二维动态数组,初始

C++创建和释放二维数组
创建int *ary = new int[sizeY];for(int i = 0; i < sizeY; ++i) { ary[i] = new int[sizeX];}释放for(int i = 0; i < sizeY; ++i) { delete [] ary[i];}delete [] ary;

C++ 二维数组的动态创建和释放(new和delete)
用new运算符动态的分配内存,用delete运算符释放这些内存 ###1、以int*为例: ####1.1、动态创建 int *channelLen; channelLen = new int[3]; ####1.2、动态释放 delete []channelLen; channelLen = NU ...

C++二维数组
二维数组二维数组就是在一维数组上多加一个维度。建议:以下四种定义方式,利用第二种更

c++中new一个二维数组
在c++中定义一个二维数组时有多种方式,下面是几种定义方式的说明:其中dataType 表示数据类型,如int byte long...1、dataType (*num)[n] = new dataType [m][n];

c++动态创建和销毁二维数组
如果二维数组中的高维确定,则可以TYPE (*p)[N] = new TYPE [][N]; 用这种方法。最常用的方法: 使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组 int *b=new int[row];//分配一个指针数组,将其首地址保存在b中 for(i=0;iusing namespace std;void func(int m,int n){ int x; int *p=new int[m]; for(int i=0;i>x; p[i][j]=rand();...

Objective - c 创建二维数组
NSArray _sectionDataStr;_sectionDataStr = [[NSArray alloc] initWithObjects: [NSArray arrayWithObjects:@"Item1", @"Item2", nil], [NSArray arrayWithObjects:@"Item1", @"Item2", @"Item3", nil], [NSArray arrayWithObjects:@"Item1", @"It...

C++编写二维数组
#include <iostream>const int Cities = 5;const int Years = 4;int main(){ using namespace std; c

C++二维数组用法
       1、 myArray [4][2]={{1, 2}, {3, 4}, {5, 6}, {7, 8}};int myArrary[0][1]=0;即没有初始化的可看作初始化为0。#include <iostream>#include <iomanip>#include <cmat

6.6 C++二维数组
第一时间关注程序猿身边的故事作者闫小林白天搬砖,晚上做梦。我有故事,你有酒么?C++二维数组C++的二维数组是指具有两个下标的数组,有些数据要依赖于两个因素才能惟一地确定,因此才会引入二维数组。C++二维数组的定义C++中定义二维数组的一般格式:类型标识符 数组名[常量表达

c++创建二维动态数组与内存释放
如下: 如上,结果如下:

i++#includeios
C++ 创建二维数组的几种方法
一、用new申请内存空间1 int *dp=new int[n];//动态申请二维数组nxm2 3 for(int i=0;i<n;++i){4 5   dp[i]=new int[m];6 7 }二、用malloc申请内存空间1 int len=100;2 3 int **dp=(int **)malloc(sizeof(int) *(len+1));for

C++二维数组数组名
二维数组数组名作用:查看二维数组所占内存空间。利用sizeof()实现代码实现:#include <iostream>using namespace std;int main() {//,{4,5,6}};cout << "二维数组占用内存空间...

C语言创建动态二维数组
动态二维数组

C++强化 | 07 二维数组
1 说在前面的话继续前行、不断攻坚克难!前面几节课,我们讲了一维数组,并把一维数组中的字符数组拿出来深入讲解!这节课开始,我们要开始讲解二维数组,二维数组有哪些需要掌


©著作权归作者所有:来自51CTO博客作者wx63516ae359314的原创作品,请联系作者获取转载授权,否则将追究法律责任
C++ 使用 new 创建二维数组
​https://blog.51cto.com/u_15839417/6003939​

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++