[問題] 2D 陣列之記憶體位址有移位情形

作者: gowrite (gowrite)   2021-05-02 07:10:22
開發平台(Platform): (Ex: Win10, Linux, ...)
GNU/Linux
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
GCC
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
N/A
問題(Question):
印象中,
陣列不管是幾維的,記憶體位址應該是連續分佈,
但實際上有規則性跳躍的情況
想問各位,這樣的行為有專有名詞嗎?
謝謝
餵入的資料(Input):
請看下方程式碼
預期的正確結果(Expected Output):
預期 二維陣列 在 row 0 到 row 1 時,
記憶體的位址也是連續,
但實際上展現出來是會跳躍 找 0 尾數為 下一個 row 的開頭
錯誤結果(Wrong Output):
無錯誤,想知道是編譯器的問題,還是 C 語言的正常規格行為
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
int row = 2;
int col = 3;
// 建立 二維 int 陣列
int **arr = malloc(sizeof(int *) * row);
for(int i=0 ; i<row ; i++){
arr[i] = malloc(sizeof(int) * col);
}
// 填入數值
for(int i=0 ; i<row ; i++){
for(int j=0 ; j<col ; j++){
arr[i][j] = i+ ((j+1)*2);
}
}
當 row = 2, col = 3 時
row :0, col :0, arr[0][0] = 2, 0x55963ccf92c0
row :0, col :1, arr[0][1] = 4, 0x55963ccf92c4
row :0, col :2, arr[0][2] = 6, 0x55963ccf92c8
row :1, col :0, arr[1][0] = 3, 0x55963ccf92e0
row :1, col :1, arr[1][1] = 5, 0x55963ccf92e4
row :1, col :2, arr[1][2] = 7, 0x55963ccf92e8
可以看到 row 1 跟 row 2 中間從 92c8 跳到了 92e0 多跳了 4 bytes
當 row = 2, col = 4 時
row :0, col :0, arr[0][0] = 2, 0x55b7ab0542c0
row :0, col :1, arr[0][1] = 4, 0x55b7ab0542c4
row :0, col :2, arr[0][2] = 6, 0x55b7ab0542c8
row :0, col :3, arr[0][3] = 8, 0x55b7ab0542cc
row :1, col :0, arr[1][0] = 3, 0x55b7ab0542e0
row :1, col :1, arr[1][1] = 5, 0x55b7ab0542e4
row :1, col :2, arr[1][2] = 7, 0x55b7ab0542e8
row :1, col :3, arr[1][3] = 9, 0x55b7ab0542ec
這樣就正常
當 row = 2, col = 5 時
row :0, col :0, arr[0][0] = 2, 0x55eea8bac2c0
row :0, col :1, arr[0][1] = 4, 0x55eea8bac2c4
row :0, col :2, arr[0][2] = 6, 0x55eea8bac2c8
row :0, col :3, arr[0][3] = 8, 0x55eea8bac2cc
row :0, col :4, arr[0][4] = 10, 0x55eea8bac2d0
row :1, col :0, arr[1][0] = 3, 0x55eea8bac2e0
row :1, col :1, arr[1][1] = 5, 0x55eea8bac2e4
row :1, col :2, arr[1][2] = 7, 0x55eea8bac2e8
row :1, col :3, arr[1][3] = 9, 0x55eea8bac2ec
row :1, col :4, arr[1][4] = 11, 0x55eea8bac2f0
居然從 c2d0 多跳了 12 個 bytes 硬是跳到 c2e0 開頭
補充說明(Supplement):
N/A
作者: LPH66 (-6.2598534e+18f)   2021-05-02 07:44:00
因為你並不是為底層結構配置連續記憶體 (你的 for/malloc)也就是說, 對系統來說你的每一列都是個別一塊記憶體因此它們之間就並不一定有什麼位置上的關係了會在附近只是因為剛好那附近都還沒人用而已要配置成連續的也不是不行, 但就不是 for/malloc 一列一列要, 而是一口氣要來一整塊之後指定每一列進列指標陣列另外, cc 到 e0 沒有連續喔, 中間還有 d
作者: F04E (Fujitsu)   2021-05-02 08:29:00
你是配置了複數個一維陣列而不是一個二維...
作者: stupid0319 (徵女友)   2021-05-02 09:25:00
malloc二維陣列應該是for loop malloc多個一維陣列編譯器沒問題,C語言也沒問題,單純只是寫法bug寫code懷疑編譯器有問題的,我是頭一個看到.........
作者: xam (聽說)   2021-05-02 12:11:00
code寫錯,懷疑編譯器/程式語言/電腦有錯的人,很多啊
作者: millaker0820 (Millaker)   2021-05-02 17:48:00
正確寫法應該是先malloc一個大小為row*col的連續記憶體,在一一把pointer指向每個row的開頭 這樣就會是連續的了
作者: Lipraxde (Lipraxde)   2021-05-02 21:19:00
很有想法 !
作者: cuteSquirrel (松鼠)   2021-05-03 10:29:00
一樓專業
作者: chchwy (mat)   2021-05-03 11:17:00
你呼叫了好多次malloc() 這樣當然沒有保證連續
作者: Qbsuran (Qbsuran)   2021-05-04 18:26:00
就算是一次分配 陣列只有1D/2D "剛好"連續

Links booklink

Contact Us: admin [ a t ] ucptt.com