C++?使用?new?創(chuàng)建二維數(shù)組實(shí)例
1. 直接創(chuàng)建
C++ 使用 new 創(chuàng)建二維數(shù)組最直接的方法就是 new T[M][N]
。返回的指針類型是 T (*)[N]
,它是指向數(shù)組的指針,可以直接使用數(shù)組下標(biāo)形式訪問(wèn)元素。釋放內(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í)行。如果覺(jué)得 T (*)[N]
繁瑣,可以直接使用 auto p = new T[M][N]
。三維數(shù)組甚至更高維數(shù)組都可以使用這種方法。例如,三維數(shù)組使用 new T[M][N][O]
進(jìn)行創(chuàng)建,依舊使用 delete[] p
進(jìn)行釋放。
為什么可以這樣寫?因?yàn)檫@種多維數(shù)組和普通的多維數(shù)組都是通過(guò)一維數(shù)組實(shí)現(xiàn)的。例如,int a[6][8]
,實(shí)際上編譯器會(huì)轉(zhuǎn)化為 int b[6 * 8]
一維數(shù)組。然后每次訪問(wèn)二維數(shù)組 a[i][j]
相當(dāng)于訪問(wèn) b[i * 8 + j]
。從二維、三維數(shù)組的轉(zhuǎn)化過(guò)程中可以發(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)換時(shí),并沒(méi)有用到第 0 維的大小,而其它維的大小都是必須的。這也就是為什么下面代碼能正確執(zhí)行。
int a[2][3]; int (*p)[3] = a;
由于多維數(shù)組本質(zhì)上是一維數(shù)組,所以釋放內(nèi)存都是 delete[] p
,而沒(méi)有奇怪的 delete[][]
語(yǔ)法。
2. 借助指針數(shù)組
還有一種方法就是先 new T*[M]
創(chuàng)建一個(gè)指針數(shù)組,其每個(gè)元素保存每一行的首個(gè)元素的地址,再使用 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])
,因?yàn)樗侵羔様?shù)組而不是數(shù)組指針。其次,需要對(duì)每一行調(diào)用 new T[N]。釋放內(nèi)存時(shí),要先使用 delete[]
釋放每一行,再調(diào)用 delete[]
釋放數(shù)組指針。這幾個(gè)步驟一步都不能錯(cuò),不然就出現(xiàn)野指針或者內(nèi)存泄漏。這段代碼我也是用 Address Sanitizer 和 Leak Sanitizer 檢查一遍才寫對(duì)。
這種方法唯一的好處就是可以創(chuàng)建交錯(cuò)數(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 對(duì)上面這種方法進(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)建了一個(gè)二維數(shù)組,第 0 行有 3 個(gè)元素,第 1 行有 4 個(gè)元素。這種方法既能創(chuàng)建交錯(cuò)數(shù)組,也不需要手動(dòng)釋放內(nèi)存。
到此這篇關(guān)于C++ 使用 new 創(chuàng)建二維數(shù)組實(shí)例的文章就介紹到這了,更多相關(guān)C++ 使用 new 創(chuàng)建二維數(shù)組內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之順序表的定義實(shí)現(xiàn)詳解
這篇文章主要介紹了c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)與算法之順序表的定義實(shí)現(xiàn)詳解,用順序存儲(chǔ)的方式實(shí)現(xiàn)線性表順序存儲(chǔ),把邏輯上相鄰的元素存儲(chǔ)在物理位置上也相鄰的存儲(chǔ)單元中,元素之間的關(guān)系由存儲(chǔ)單元的鄰接關(guān)系來(lái)體現(xiàn),需要的朋友可以參考下2023-08-08簡(jiǎn)單總結(jié)C語(yǔ)言中的運(yùn)算符優(yōu)先級(jí)
這篇文章主要介紹了C語(yǔ)言中的運(yùn)算符優(yōu)先級(jí),文中簡(jiǎn)單總結(jié)了一些常用運(yùn)算符的優(yōu)先級(jí)順序以及記憶技巧,需要的朋友可以參考下2016-05-05VC6.0實(shí)現(xiàn)讀取Excel數(shù)據(jù)的方法
這篇文章主要介紹了VC6.0實(shí)現(xiàn)讀取Excel數(shù)據(jù)的方法,非常實(shí)用的功能,需要的朋友可以參考下2014-07-07解決Qt設(shè)置QTextEdit行高的問(wèn)題
這篇文章介紹了Qt設(shè)置QTextEdit行高的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04C語(yǔ)言中main函數(shù)兩個(gè)參數(shù)的作用
這篇文章主要介紹了C語(yǔ)言中main函數(shù)兩個(gè)參數(shù)的作用,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09Cocos2d-x保存用戶游戲數(shù)據(jù)之XML文件是否存在問(wèn)題判斷方法
這篇文章主要介紹了Cocos2d-x保存用戶游戲數(shù)據(jù)之XML文件是否存在問(wèn)題判斷方法,請(qǐng)注意代碼中包含大量注釋,需要的朋友可以參考下2014-09-09C語(yǔ)言中g(shù)etchar()的返回類型為什么是int詳解
這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中g(shù)etchar()的返回類型為什么是int的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11C語(yǔ)言 以數(shù)據(jù)塊的形式讀寫文件詳解及實(shí)現(xiàn)代碼
本文主要介紹 C語(yǔ)言 以數(shù)據(jù)塊的形式讀寫文件,這里對(duì)相關(guān)知識(shí)資料做了整理,并附代碼示例,以便大家學(xué)習(xí)參考,有學(xué)習(xí)此部分知識(shí)的朋友可以參考下2016-08-08Qt6.0+vs2019環(huán)境配置的實(shí)現(xiàn)教程
這篇文章主要介紹了Qt6.0+vs2019環(huán)境配置的實(shí)現(xiàn)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03C++實(shí)現(xiàn)LeetCode(38.計(jì)數(shù)和讀法)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(38.計(jì)數(shù)和讀法),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07