簡體   English   中英

關於 malloc/free 中使用的數組指針的問題

[英]Question about pointer to array used in malloc/free

我看到了以下代碼:

#include <stdlib.h>

void foo(char n)
{
    int (*vals)[n] = malloc(sizeof(int[n]));

    for (int i = 0; i < n; ++i)
        (*vals)[i] = i;

    free(vals);
}

int main(int argc, char **argv)
{
    foo(*(argv[1]));

    return 0;
}

這條線讓我很不舒服:

free(vals);

vals是指向數組的指針。 這看起來不錯,但我就是很難將其內化,我不知道為什么。

我比較習慣下面的風格:

int *p = (int*)malloc(n * sizeof(int));
......
free(p);

在這段代碼中, p是一個指針,指向一些整數的 memory 區域的開始,malloc 和 free 是對稱的,因為它們都在指針類型上工作; 然而原始代碼有malloc()處理指向數組的指針,而free()處理指針。

出於好奇,我修改了原來的代碼:

free(vals);  ==>  free(*vals);

我原以為這個更改會在編譯器中失敗,原因是*vals現在是一個數組。 但是 gcc 很好,valgrind 不會抱怨 memory 泄漏。

我知道 C 在 function 調用中有一個叫做數組退化為指針的東西。 但我就是無法將這些東西內化。 抱歉寫了這么長的時間來描述一個問題,希望你能看到我的掙扎。 是否有明確的文檔/stackoverflow/blog 來解決這個問題——最好是 C99 或更高版本?

謝謝!

free(*vals); 與寫free(vals);

編輯您的代碼以清除一點

#include <stdlib.h>
#include <stdio.h>

void foo(char n)
{
    int (*vals)[n] = malloc(sizeof(int[n]));

    for (int i = 0; i < n; ++i)
        (*vals)[i] = i;

    printf("*val is %p\n", *vals);
    printf("val is %p\n", vals);
    printf("&val is %p\n", &vals);
    
    free(vals);
}

int main()
{
    foo(10);
    
    return 0;
}

這是 output:

*val is 0000018190365d50
val is 0000018190365d50
&val is 0000005d9dbff7b8

請注意, vals是數組指針,這意味着它的基本類型是n 個整數的數組,其中指針val在該堆棧中創建並指向整個數組,而不僅僅是第一個元素,並且該數組是在heap創建的,以說明,請看下圖:

在此處輸入圖像描述

所以例如,如果你寫:

printf("val is %p\n", vals);
printf("val+1 is %p\n", vals+1);

output 將是:

val is 00000207ef0c5d50
val+1 is 00000207ef0c5d78

請注意,兩者之間的差異約為40個字節,因為val指向整個數組,而不僅僅是一個元素,如int *p = (int*)malloc(n * sizeof(int));

請注意,當我說它指向整個數組時,我的意思也是它指向數組的基址。

*Vals的情況下,請看下一張圖:

在此處輸入圖像描述

*Vals只是數組第一個元素的地址,順便說一下,它與數組的基地址相同。

參考free() manual ,他們說:

free() function 釋放 ptr 指向的 memory 空間,該空間必須由先前調用 malloc()、calloc() 或 realloc() 返回。 否則,或者如果之前已經調用過 free(ptr),則會發生未定義的行為。 如果 ptr 為 NULL,則不執行任何操作。

malloc() function 返回什么?

它返回堆中保留空間的基址,因此寫成free(vals); 與寫free(vals);

此代碼使用動態 VLA 我認為如果代碼用typedef重新表述可能更容易理解。

void foo(char n)
{
    typedef int T[n];
    T *vals = malloc(sizeof(T));

    ...
  
    free(vals);
}

現在它看起來像是對單個動態 object 的簡單使用。

要首先訪問數組的元素,必須取消引用指針*vals形成一個數組,該數組衰減為適合[]運算符的int*指針。

暫無
暫無

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

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