我覺得有兩種很自然的想法。
由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...