網(wǎng)站首頁 編程語言 正文
1. 直接創(chuàng)建
C++ 使用 new 創(chuàng)建二維數(shù)組最直接的方法就是?new T[M][N]
。返回的指針類型是?T (*)[N]
,它是指向數(shù)組的指針,可以直接使用數(shù)組下標(biāo)形式訪問元素。釋放內(nèi)存直接使用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; }
執(zhí)行結(jié)果:
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 的構(gòu)造函數(shù)和析構(gòu)函數(shù)正常執(zhí)行。如果覺得?T (*)[N]
?繁瑣,可以直接使用?auto p = new T[M][N]
。三維數(shù)組甚至更高維數(shù)組都可以使用這種方法。例如,三維數(shù)組使用?new T[M][N][O]
?進(jìn)行創(chuàng)建,依舊使用?delete[] p
?進(jìn)行釋放。
為什么可以這樣寫?因為這種多維數(shù)組和普通的多維數(shù)組都是通過一維數(shù)組實現(xiàn)的。例如,int a[6][8]
,實際上編譯器會轉(zhuǎn)化為?int b[6 * 8]
?一維數(shù)組。然后每次訪問二維數(shù)組?a[i][j]
?相當(dāng)于訪問?b[i * 8 + j]
。從二維、三維數(shù)組的轉(zhuǎn)化過程中可以發(fā)現(xiàn)一些規(guī)律。
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]
編譯器進(jìn)行下標(biāo)轉(zhuǎn)換時,并沒有用到第 0 維的大小,而其它維的大小都是必須的。這也就是為什么下面代碼能正確執(zhí)行。
int a[2][3]; int (*p)[3] = a;
由于多維數(shù)組本質(zhì)上是一維數(shù)組,所以釋放內(nèi)存都是?delete[] p
,而沒有奇怪的?delete[][]
?語法。
2. 借助指針數(shù)組
還有一種方法就是先?new T*[M]
?創(chuàng)建一個指針數(shù)組,其每個元素保存每一行的首個元素的地址,再使用?new T[N]
?創(chuàng)建每一行。示例代碼如下:
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])
,因為它是指針數(shù)組而不是數(shù)組指針。其次,需要對每一行調(diào)用 new T[N]。釋放內(nèi)存時,要先使用?delete[]
?釋放每一行,再調(diào)用?delete[]
?釋放數(shù)組指針。這幾個步驟一步都不能錯,不然就出現(xiàn)野指針或者內(nèi)存泄漏。這段代碼我也是用 Address Sanitizer 和 Leak Sanitizer 檢查一遍才寫對。
這種方法唯一的好處就是可以創(chuàng)建交錯數(shù)組(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 對上面這種方法進(jìn)行包裝,使其更加易用。示例代碼如下:
std::vector<std::vector<int>> v{ std::vector<int>(3), std::vector<int>(4) }; std::cout << v[0].size() << " " << v[1].size() << std::endl;
這段代碼創(chuàng)建了一個二維數(shù)組,第 0 行有 3 個元素,第 1 行有 4 個元素。這種方法既能創(chuàng)建交錯數(shù)組,也不需要手動釋放內(nèi)存。
原文鏈接:https://www.cnblogs.com/mkckr0/p/17045233.html
相關(guān)推薦
- 2022-10-08 C#中LINQ的Select與SelectMany函數(shù)使用_C#教程
- 2022-10-01 使用C++實現(xiàn)插件模式時的避坑要點(推薦)_C 語言
- 2022-05-23 python中3種等待元素出現(xiàn)的方法總結(jié)_python
- 2022-10-18 C++中智能指針最常用的shared_ptr和unique_ptr_C 語言
- 2024-03-06 SpringAOP基于注解方式實現(xiàn)和細(xì)節(jié)
- 2022-11-22 在?React?項目中全量使用?Hooks的方法_React
- 2022-08-25 windows下搭建Consul集群_云其它
- 2022-06-18 C#讀寫Config配置文件案例_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支