簡體   English   中英

動態分配數組解釋

[英]Dynamically allocating array explain

這是我的老師向我們展示的示例代碼“如何在C中動態分配數組?”。 但我不完全理解這一點。 這是代碼:

int k;
int** test;
printf("Enter a value for k: ");
scanf("%d", &k);
test = (int **)malloc(k * sizeof(int*));
for (i = 0; i < k; i++) {
    test[i] = (int*)malloc(k * sizeof(int)); //Initialize all the values
}

我想在C中定義一個數組,你必須把[]放在名字之后,那么究竟是什么是int** test ; 它不僅僅是一個指針指針嗎? malloc()系列也讓我很困惑.....

根據聲明int** test; test指向指針的指針 ,代碼pice使用malloc函數動態分配int值矩陣的內存。

聲明:

test = (int **)malloc(k * sizeof(int*));
    //                ^^------^^-------
    //  allocate for  k  int*  values    

k指針( int* )分配繼續內存。 所以假設如果k = 4那么你會得到類似的東西:

 temp      343  347  351  355
+----+    +----+----+----+----+
|343 |---►| ?  | ?  | ?  |  ? |
+----+    +----+----+----+----+

我假設地址是四個字節和? 意味着垃圾值。

temp分配返回的地址,malloc分配大小= k * sizeof(int**)繼續內存塊,在我的例子中= 16字節。

在for循環中,為k int分配內存並將返回的地址分配給temp[i] (先前分配的數組的位置)。

test[i] = (int*)malloc(k * sizeof(int)); //Initialize all the values
//                     ^^-----^^----------
//       allocate for  k   int  values    

注意:表達式temp[i] == *(temp + i) 因此,在每次迭代中的for循環中,為k int值數組分配內存,如下所示:

   First malloc                     For loop   
  ---------------                  ------------------
       temp
      +-----+
      | 343 |--+
      +-----+  |
               ▼                    201   205   209    213  
        +--------+                +-----+-----+-----+-----+
 343    |        |= *(temp + 0)   |  ?  |  ?  |  ?  | ?   |  //for i = 0
        |temp[0] |-------|        +-----+-----+-----+-----+
        | 201    |       +-----------▲
        +--------+                  502   506  510    514
        |        |                +-----+-----+-----+-----+
 347    |temp[1] |= *(temp + 1)   |  ?  |  ?  |  ?  | ?   |  //for i = 1
        | 502    |-------|        +-----+-----+-----+-----+
        +--------+       +-----------▲
        |        |                  43    48    52    56
 351    | 43     |                +-----+-----+-----+-----+
        |temp[2] |= *(temp + 2)   |  ?  |  ?  |  ?  | ?   |  //for i = 2
        |        |-------|        +-----+-----+-----+-----+
        +--------+       +-----------▲
 355    |        |
        | 9002   |                 9002  9006   9010 9014
        |temp[3] |                +-----+-----+-----+-----+
        |        |= *(temp + 3)   |  ?  |  ?  |  ?  | ?   |  //for i = 3
        +--------+       |        +-----+-----+-----+-----+
                         +-----------▲

又一次? 意味着垃圾值。

附加要點:

1)您正在通過malloc轉換返回的地址,但在C中您應該避免它。 閱讀我是否轉換了malloc的結果? 只需按以下步驟操作:

test = malloc(k* sizeof(int*));
for (i = 0; i < k; i++){
    test[i] = malloc(k * sizeof(int));
}

2)如果要動態分配內存,則需要在完成工作后明確釋放內存(在釋放動態分配的內存后,無法訪問該內存)。 釋放內存進行test步驟如下:

for (i = 0; i < k; i++){
    free(test[i]);
}
free(test);

3)如果你想為所有數組分配完全連續的內存,這是為2D矩陣分配內存作為數組的一種方法檢查這個答案: 在函數C中分配內存2d數組

4)如果描述有幫助,並且您想學習3D分配,請檢查以下答案: 字符串矩陣或/ 3D字符數組

請記住,數組衰減為指針,可以用作指針。 並且該指針可以用作數組。 實際上,索引數組可以看作是一個表單或指針算術。 例如

int a[3] = { 1, 2, 3 };  /* Define and initialize an array */
printf("a[1] = %d\n", a[1]);  /* Use array indexing */
printf("*(a + 1) = %d\n", *(a + 1));  /* Use pointer arithmetic */

上面的兩個輸出都將打印數組中的第二個(索引1 )項。

關於指針也是如此,它們可以與指針算法一起使用,或者與數組索引一起使用。

根據以上所述,可以認為一個指針到指針-to.type的作為陣列的陣列-的式。 但這不是全部真相,因為它們在內存中的存儲方式不同。 所以你不能將一個數組數組作為參數傳遞給一個需要一個指向指針的函數。 但是,在初始化之后,可以使用帶有數組索引的指針指針,就像普通指針一樣。

malloc用於動態地將內存分配給測試變量,將*視為數組,**視為數組數組,但不是通過值傳遞,指針用於引用變量的內存地址。 當調用malloc時,您通過獲取整數的大小並乘以用戶提供的int數來為測試變量分配內存,因為在用戶輸入之前不知道這一點。

是的,完全沒問題。 test是指向指針的指針,所以test[i]相當於寫test + i將是一個指針。 為了更好地理解,請查看此c - 常見問題解答

確實如此, int**是指向指針的指針。 我們也可以說它是一個指針數組。

test = (int **) malloc(k * sizeof(int*));

這將首先分配一個k指針數組。 malloc動態分配內存。

test[i] = (int*) malloc(k * sizeof(int));

這不是必需的,因為它足夠了

test[i] = (int*) malloc(sizeof(int*));

這里我們分配每個數組位置以指向有效的內存。 但是對於像int這樣的基類型,這種分配沒有意義。 它適用於較大的類型(結構)。

每個指針都可以像數組一樣被訪問,反之亦然,例如,以下是等效的。

int a;
test[i] = &a;
(test + i) = &a;

這可能是內存中的數組test ,從偏移量0x10000000開始分配:

+------------+------------+
|   OFFSET   |  POINTER   |
+------------+------------+
| 0x10000000 | 0x20000000 | test[0]
+------------+------------+
| 0x10000004 | 0x30000000 | test[1]
+------------+------------+
| ...        | ...

每個元素(在此示例中為0x2000000和0x30000000)是指向另一個已分配內存的指針。

+------------+------------+
|   OFFSET   |    VALUE   |
+------------+------------+
| 0x20000000 | 0x00000001 | *(test[0]) = 1
+------------+------------+
| ...
+------------+------------+
| 0x30000000 | 0x00000002 | *(test[1]) = 2
+------------+------------+
| ...

每個值僅包含sizeof(int)的空間。

在這個例子中, test[0][0]等價於*(test[0]) ,但是test[0][1]無效,因為它會訪問未分配的內存。

對於每種類型T,存在類型“指向T的指針”。

可以通過* type聲明符將變量聲明為指向各種類型的值的指針。 要將變量聲明為指針,請在其名稱前面加上星號。

因此“對於每個類型T”也適用於指針類型,存在多個間接指針,如char **或int ***等。 還存在“指向數組的指針”類型,但它們不像“指針數組”那么常見( http://en.wikipedia.org/wiki/C_data_types

所以int** test聲明一個指向“int數組”的指針數組

在行test = (int **)malloc(k*sizeof(int*)); 為k量( int* )提供足夠的內存

所以有k個指針,每個都指向......

test[i] = (int*)malloc(k * sizeof(int)); (每個指針指向一個大小為k ints數量的數組)

摘要...

int** test; 由k個指針組成,每個指針指向k個量的int。

int **是指向int指針的指針。 看看“左右”規則

暫無
暫無

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

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