簡體   English   中英

雙指針是什么意思和指針日期類型的大小的malloc

[英]What does double pointer mean and malloc of size of pointer date type

int **matrix, i, j;
matrix = malloc(5 * sizeof(int*));
*matrix = malloc(20 * sizeof(int));

我只是不了解雙指針的概念以及它如何轉換為二維數組(也就是說,它是真的)。​​謝謝。

從技術上講,這里創建的不是2D數組而是指針數組,每個指針都包含數組的起始地址。 然后可以將其索引為“真實” 2D數組。

這行代碼創建了一個由5個指向int指針的數組:

matrix = malloc(5 * sizeof(int*));

下一行創建一個單個數組20 int

*matrix = malloc(20 * sizeof(int));

但是,這在2D數組方面是不完整的,因為僅分配了一行。 您需要遍歷matrix指向的每個元素以創建每一行:

int **matrix, i;

matrix = malloc(5 * sizeof(int*));
for (i=0; i<5; i++) {
    matrix[i] = malloc(20 * sizeof(int));
}

使用完此動態2D數組后,您需要按相反的順序釋放內存:

for (i=0; i<5; i++) {
    free(matrix[i]);
}
free(matrix);

這與真實的2D陣列在某些方面有所不同。 首先,在真正的2D數組中,所有元素在內存中都是連續的,在這種情況下,指針數組和每個行數組都不是。

另一個區別是,傳遞給函數時,傳遞傳遞的方式與傳遞真實2D數組的傳遞方式不同。

對於簡單的一維數組,無論是在編譯時分配還是動態分配:

int a1[5];
int *a2 = malloc(5 * sizeof(int));

兩者都可以傳遞給這樣的函數:

void f(int *a);

但是對於2D數組:

int a[5][20];

它需要傳遞給這樣的函數:

void f(int a[5][20]);

或等效地:

void f(int (*a)[20]);

而動態2D數組需要傳遞給這樣的函數:

void f(int **a);

一些圖片可能會有所幫助。

讓我們從matrix開始,它是一個指向int指針:

  int **
+--------+
| matrix |---???
+--------+

在第一次調用malloc ,您將擁有以下內容:

  int **        int *
+--------+    +-----------+
| matrix |--->| matrix[0] |
+--------+    +-----------+
              | matrix[1] |
              +-----------+
              | matrix[2] |
              +-----------+
              | matrix[3] |
              +-----------+
              | matrix[4] |
              +-----------+

您已經為5個int *對象動態分配了空間,並且matrix指向第一個。 在第二次調用malloc ,您有了這個(表達式*matrix等效於matrix[0] -有關下面的更多內容):

  int **        int *            int
+--------+    +-----------+    +---------------+
| matrix |--->| matrix[0] |--->| matrix[0][0]  | 
+--------+    +-----------+    +---------------+
              | matrix[1] |    | matrix[0][1]  |
              +-----------+    +---------------+
              | matrix[2] |    | matrix[0][2]  |
              +-----------+    +---------------+
              | matrix[3] |           ...
              +-----------+    +---------------+
              | matrix[4] |    | matrix[0][19] |
              +-----------+    +---------------+

您已經為20個int對象動態分配了空間,並且matrix[0]指向第一個對象。

因此,簡而言之,每個matrix[i][j]是一個int 每個matrix[i]指向matrix[i][0] ,因此每個matrix[i]必須是一個指向intint *的指針。 matrix指向matrix[0] ,這意味着matrix必須是int *int **的指針。

請記住,數組下標表達式a[i] 定義*(a + i) -給定地址a ,從該地址偏移i 元素 (不是字節!),並尊重結果。 因此, *matrix等效於*(matrix + 0) ,等效於matrix[0]

現在,這里沒有一個真正的2D數組-您有一個指針序列,每個指針都可能指向一個int對象序列的第一個(或根本沒有指向)。 陣列的“行”在內存中將很可能不相鄰。 在真正的2D數組中,所有數組元素都是連續的。 給定

int matrix[5][20];

元素將如下所示:

+---------------+
| matrix[0][0]  |
+---------------+
| matrix[0][1]  |
+---------------+
      ...
+---------------+
| matrix[0][19] |
+---------------+
| matrix[1][0]  |
+---------------+
| matrix[1][1]  |
+---------------+
       ...
+---------------+
| matrix[4][19] |
+---------------+

編輯

指針到指針和2D數組之間的其他一些關鍵區別。 首先,假設以下定義:

int **ptr;
int matrix[ROWS][COLS];
  1. 表達式ptr類型為int ** 表達式matrix將從int [ROWS][COLS]類型“衰減”到int (*)[COLS] (指向COLS int元素數組的指針);

  2. sizeof ptr給出指針本身的大小(4、8或其他一些字節數)。 sizeof matrix以字節為單位給出整個數組的大小( ROW * COLS * sizeof (int) )。

  3. 表達式&matrixmatrix&matrix[0]&matrix[0][0]都將產生相同的 (數組第一個元素的地址),盡管表達式的類型將不同int (*)[ROWS][COLS]int (*)[COLS]int (*)[COLS]int * 表達式&ptrptr&ptr[0]&ptr[0][0]都不會產生相同的值- &ptr&ptr[0][0]值將不同於ptr&ptr[0] ,並且表達式的類型為int ***int **int **int *

我認為您需要以下條件:

int **matrix, i, j;
matrix = malloc(5 * sizeof(int*));
for (int i=0; i<5; i++)
    matrix[i] = malloc(20 * sizeof(int));

在這里,您首先分配一個指向行的指針數組。 然后,您為每一行分配內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM