C 使用new分配二維陣列的一些想法和建議

2021-10-10 15:37:24 字數 3807 閱讀 2396

我覺得有兩種很自然的想法。

由m個一維陣列組成

二維陣列其實就是乙個一維陣列。

上面兩種方式並不矛盾,展現了二維陣列在記憶體中的組織形式。下面分析我們經常看到的兩種寫法。

我相信這個**,大家都經常用,尤其在使用c語言(malloc/free)的時候。

下面簡要的分析下流程。

分配:先建立陣列名array(分配多少行),在for迴圈中分配列。

釋放:先釋放每行陣列,最後釋放array

備註:這種反向操作的是很常見的,比如棧就符合,構造/析構。從邏輯上、物理上符合棧,可以找到很多例子。

// 建立二維陣列 array[2][3]

int*

* array = new int*[

2];// 先分配行--2行

for(size_t i =

0; i <

2; i++

) array[i]

= new int[3

];// 後分配列--3列

int i =0;

for(

int r =

0; r <

2; r++

)// 訪問

for(

int c =

0; c <

3; c++

) array[r]

[c]= i++

;// 釋放 array[2][3]

for(

int i =

0; i <2;

++i)

// 釋放和分配是反著的,先釋放每行陣列

if(array[i]

!= nullptr)

delete[

] array[i];if

(array == nullptr)

// 釋放陣列名--第一步分配的

delete[

] array;

// 這裡要用delete

為什麼說由m個一維陣列組成?從感覺上就知道,每一次for迴圈建立乙個一維陣列,大部分情況下,這2個陣列都不是挨著的

當然,陣列內是相鄰的

陣列間不相鄰

咋一看,這份**比上面清晰,簡潔很多,不需要用for分配陣列,也不需要用for釋放記憶體

當然,也有人會懷疑這**釋放記憶體有問題

其實,這份**沒有問題,此時你會有乙個疑問,delete釋放當個元素,delete釋放一維陣列

難道delete也可以釋放多維陣列,可以肯定的是教科書上從來沒有這麼講,也沒有有人敢這麼說,這本就是錯的。

但是,有一種情況下是對的,二維陣列本就是連續的(記憶體),它本就是一維陣列。同時對於三維陣列,或者高維陣列也是對的!!!
// 建立二維陣列 array[2][3]

int(

*array)[3

]=newint[2

][3]

;if(array ==

nullptr

)return0;

int i =0;

for(

int r =

0; r <

2; r++

)// 訪問

for(

int c =

0; c <

3; c++

) array[r]

[c]= i++

;// 釋放 array[2][3]

if(array !=

nullptr

)// 能理解為什麼delete可以用在二維陣列上了把,本質是乙個一維陣列

delete

array;

從感覺上就知道,一次性分配好,很可能是連續的(一維陣列)。

當然,陣列內是相鄰的

陣列間也是相鄰的!!!

總結:這兩種分配的最本質的區別,就是連續與否(各一維陣列是否連續)

這裡就引出乙個問題,如果陣列總數量很大,比如幾w個,第二種就會多次尋找符合這樣大的連續記憶體的空間,當然對於記憶體較小的微控制器,微機這是很不現實,也很難實現。反之,使用第一種分配方式就把壓力減少到1/m。

一些建議

對於第一種方式,適合在記憶體資源要求嚴格的地方,當然c語言malloc/free也是這一梯隊。比如微控制器等。這裡給出乙個概念,1m能存可以存 216=

65536

2^=65536

216=65

536個int,剛好是windows棧爆。缺點:分配和釋放需要for,繁雜第二種方式,**簡潔,易懂,更加貼近人的思維。但是由於分配的陣列是連續的,在找這個大記憶體塊造成了壓力。如果你的記憶體很大,當然可以忽略,如果你是c++選手,可以寫的更加簡單

// 建立二維陣列 array[2][3]

auto array =

newint[2

][3]

;int i =0;

for(

int r =

0; r <

2; r++

)// 訪問

for(

int c =

0; c <

3; c++

) array[r]

[c]= i++

;// 釋放 array[2][3]

delete

array;

當然,這種方式還可以適合三維陣列,高維陣列,優勢就來了。

// 建立三維陣列 array[2][3][4]

auto array =

newint[2

][3]

[4];

// (*array)[3][4]

int i =0;

for(

int r =

0; r <

2; r++

)// 訪問

for(

int c =

0; c <

3; c++

)for

(int h =

0; h <

4; h++

) array[r]

[c][h]

= i++

;delete

array;

這就是典型的陣列指標,它的本質是陣列,而陣列元素存的是指標。其實陣列指標非常常見,裡面還可以存函式,也就是函式指標,比如array是function name;當然有時候還省略名字(*)[2],看到把*用括號包起來絕對是函式指標,,,

這裡分享如何記住陣列指標和指標陣列?

誰在前,本質就是誰

陣列指標:陣列在前,本質是陣列,而陣列元素存的是指標

指標陣列:指標在前,本質是指標,指向的是陣列

C 使用new建立二維陣列

include using namespace std void main 以上是一般的程式,需要注意的是,記憶體空間的劃分是5行10列,但是p的維度是按照列,而不是按照行宣告的。在自己編寫benchmark,執行在cpu上時,預期是宣告16 128的陣列,這樣每行是128 4 因為int 4byt...

c 關於new動態分配記憶體給一維二維陣列的問題

1 用new動態分配記憶體給一維陣列 includeint main 這裡是動態分配10個int的記憶體,並把首元素的位址返回。記住在動態分配的時候,不需要寫int p 10 來表達這是指向10個int的陣列,因為new返回的是第乙個值的位址,而第乙個值是int,所以應該用int 2 用new動態分...

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...