簡體   English   中英

為什么在取消引用數組指針時 C 程序會崩潰?

[英]Why does C program crash when dereferencing pointer to an array?

我有一個簡單的 C 代碼:

int main()
{
    int test[10] = {1,2,3,4,5,6,7,8,9,10};
    int **ptr = &test;

    printf("%d\n", (*ptr)[0]);

    return 0;
}

一旦到達printf行,它就會崩潰:

Process returned -1073741819 (0xC0000005)   execution time : 0.865 s

在 Ubuntu 上編譯代碼時,它給了我警告:

test.c:8:17: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
     int **ptr = &test;

但是,如果我改為在堆上動態分配內存,則代碼有效:

int main()
{
    int *test = malloc(sizeof(int)*10);
    for (int i = 0; i < 10; i++) {
        test[i]=i;
    }
    int **ptr = &test;

    printf("%d\n", (*ptr)[1]);

    return 0;
}

請向我解釋,為什么當數組在堆上而不在堆棧上時代碼有效?

為了讓你的ptr變量成為“整數數組的地址”,你實際上需要一個更微妙(和神秘)的聲明。

這將起作用:

int (*ptr)[10] = &test;

正如它聲明的那樣,當取消引用時(即當您實際使用表達式*ptr ),它將是一個數組(包含 10 個元素)。

在某些方面,聲明的結構有點類似於函數指針的結構

編輯:在您的第二種情況下, test是一個普通的舊指針(由malloc調用分配給它的值); 因此,它本身就是一個可以獲取其地址的變量(正如您的int **ptr = &test;行所做的那樣 - 正確)。

但是,在第一種情況下(“固定”數組), test指的是一塊內存; 在許多方面, this 可以用作指向第一個元素的指針(例如,就像在函數調用中一樣)。 但是編譯器可能會為“第一個元素的地址的地址”分配什么值? 這就是在這種情況下使用&test嘗試分配失敗的原因。

但是,根據上一段,您有權問,編譯器如何使用此答案中給出的代碼確定&test (分配給ptr )的值? 好吧,如果您將以下行添加到您的程序中:

printf("%p %p\n", test, &test);

您將看到test&test (您可以為ptr更改&test - 輸出將相同)具有完全相同的值 因此,使用這個“神秘”聲明,你給編譯器足夠的信息來知道如何處理“數組指針”——基本上,它有點“忽略”(或繞過)第一級解引用,以地址結束數組的第一個元素(按原樣)。

暫無
暫無

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

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