動態陣列(一維二維)探秘

2021-10-01 16:45:46 字數 2690 閱讀 2612

因為做leetcode的一道演算法題

,需要用到二維陣列,結果自己在理解和使用上有很大誤解,所以單獨拿出來,從記憶體等各方面透徹的梳理一遍。

char * a = (char*)malloc(8 * sizeof(char

)); memset(a,

0, 8

);

for (int i = 0; i < 8; i++)

for (int i = 0; i < 8; i++)

for (int i = 0; i < 8; i++)

free(a);

輸出內容abcdefghabcdefgh

這樣申請與char a[8]是一樣的,不管是底層實現還是使用,都是一樣的,這就是乙個8個位元組長度的陣列。我們看記憶體,也是一段連續的資料。

釋放記憶體的時候,系統可以根據記憶體管理把這連續的8個位元組的空間**。

char a[8][4] = ;

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

}

輸出結果 aaaabbbbccccddddeeeeffffgggghhhh

我們看一下記憶體

是一段連續的記憶體,陣列a[n][m],按照m跳度,前m個是第乙個n的序列,然後是第二個n的m個序列,實際上這是乙個一維陣列。

char** a = (char**)malloc(8 * sizeof(char*));

for (int i = 0; i < 8; i++)

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

}

a是乙個陣列,也就是a指向了申請的一塊空間,空間是8個char*大小。然後為a的每乙個陣列元素,又指向了一塊空間,空間是4個char大小。記憶體空間如圖所示,a指向了一塊空間,有8個元素,每個元素的空間用來儲存了乙個char*的資料,也就是char的指標,a算是乙個指向指標的指標。a是乙個指標,指向了一塊資料,這塊資料儲存的是乙個指標,指向了一塊資料,這塊資料儲存的是乙個4位元組的char。

我們看一下實際的記憶體位址

這是char*陣列a的資料,8個char*的空間,標藍的是第乙個a+0儲存的資料,是乙個指標位址,因為是32位的,所以是4個位元組,翻譯過來就是0x00557600

我們看一下a的第一塊資料指向的內容,是一塊資料,儲存了aaaa,四個a。

這就是二維陣列的實質。一維陣列a指向了一塊資料,儲存的是字元,二維陣列指向了一塊資料,儲存的相當於是乙個一維陣列指標的列表,每個二維陣列元素相當於乙個一維陣列。以此類推,三維陣列就是儲存了乙個二維陣列指標的列表。

它是如何訪問資料的呢,與一維陣列一樣,先通過a+i訪問到a的元素指標,然後通過*(a+i)訪問到資料,這個資料又是個陣列,通過*(a+i)+j訪問到元素指標,再通過*(*(a+i)+j)訪問到資料,最後提醒,別忘了釋放空間。

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

free(a);

我們看到,如果通過char a[8][4]申請乙個二維陣列,實際上空間是連續的,我們能不能模擬呢,這樣整塊申請記憶體,效率更高。**如下

char* a = (char*)malloc(8 * 4 * sizeof(char

));

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

}free(a);

申請了乙個一維陣列,大小是a[n][m]中n*m個陣列元素個數。訪問呢,就模仿二維陣列的訪問,m個元素是一組。記憶體如下

這裡有乙個小小的一問,char a[8][4]這種可以通過 a[1][2]訪問,但是這種方式不行。char[8][4]系統知道是乙個二維陣列,保留了它的資訊,知道如何跳,而char* a = (char*)malloc(8 * 4 * sizeof(char));

系統認為是一維陣列,按照二維的那種方式跳,就會執行錯誤。

除了malloc,也可以用new,更方便一些

char * a = new

char[8]();

減少了初始化的步驟,這裡就是建立一塊空間,大小是8,單位是char,呼叫()初始化。這裡()的意思就是呼叫預設建構函式等於new char[8]{}

上面的方法空間在一起了,但是無法用二維陣列的方式訪問 ,很彆扭,那麼有沒有動態二維陣列呢,上面插曲的new為我們提供了方法。

auto a = new

char[8][4

]();

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

}delete(a);

這種方法的實質是什麼呢?實際上就是第二種方法,只不過告訴了系統,這是乙個二維陣列。那麼二維陣列的指標怎麼定義呢?可以用如下代替

char(* a)[4] = (char(*)[4])malloc(8 * 4 * sizeof(char

));

for (int i = 0; i < 8; i++)

}for (int i = 0; i < 8; i++)

}free(a);

二維動態陣列

之前都是寫的小程式,一直用的靜態陣列,也沒出現問題。可是,最近碰到大型程式和工程,這時就要用動態陣列了。因為靜態陣列時儲存在棧中的,而動態陣列儲存在堆中。計算機的棧只有1m大小,而堆可以理論上達到計算機記憶體大小,可見當大型工程資料量非常大時,必須使用動態陣列了。c 的動態陣列的建立和刪除要用到ne...

c c 動態申請一維,二維陣列

指標變數名 new 型別名 下標表示式 下標表示式 不是常量表示式,即它的值不必在編譯時確定,可以在執行時確定。這就是堆的乙個非常顯著的特點,有的時候程式設計師本身都不知道要申請能夠多少記憶體的時候,堆就變的格外有用。1.動態申請一維陣列 int p new int n if p null retu...

mysql二維轉一維 二維陣列轉為一維陣列

1.很多時候會遇到二維陣列,轉為一維陣列的時候會很苦惱,尤其是剛剛接觸php的phper。如下 將 arr轉化為一維陣列 arr array array uuid aaaaa array uuid bbbbb array uuid ccccc array uuid sssss array uuid ...