簡體   English   中英

由於某些原因,指針地址為NULL

[英]The pointer address is NULL for some reasons

這是一個顯示指針地址的簡單程序:

#include <stdio.h>

int main(void)
{
    int *a;
    int *b;

    printf ("address of a : %p, the address of b : %p\n", a, b);
    return (0);
}

所以輸出是這樣的:

address of a : 0x7fff537b1ad8, the address of b : 0x0

我的問題是:為什么變量b具有無效的地址存儲器,但變量a沒有

兩個指針都指向無效的內存。 僅因為指針指向看似有效的內存位置,並不表示它在程序上下文中有效。

為了詳細說明,其中的內存位置a來,是不是分配給你的程序點,所以從應用程序的角度來看,它是無效的記憶。 任何讀取或寫入的嘗試都將調用未定義的行為。

換句話說,絕對不能保證b將保持NULL值,它也可以具有其他看似正確但無效的內存地址。 無論它們指向的內存位置如何,它們都是無效的。

您實際上並沒有打印指針的地址。 您正在打印這些指針的 並且由於變量未初始化,因此它們具有不確定的值。

您需要使用address-of運算符來獲取其地址:

printf("address of a : %p, the address of b : %p\n", (void *)&a, (void *)&b);

還要注意,這是需要強制轉換為void *的少數情況之一。

局部變量具有自動存儲持續時間(超出范圍,可能分配了堆棧)。

要使用自動存儲持續時間(未獲取其地址)訪問未初始化的變量,則會調用未定義的行為。 當您這樣做時,任何事情都可能發生。

此外,具有自動存儲持續時間的未初始化變量具有不確定的值 這意味着它可以包含任何值,包括垃圾,零或有效地址。 如果您執行兩次程序或在程序中讀取兩次變量,則不需要兩次返回相同的值。 在某些外來系統上,如果該值是陷阱表示,則訪問具有不確定值的變量可能會導致未定義行為。

簡介:由於C語言或其他任何人都沒有保證,因此無法說明該代碼將做什么。 對此類代碼的作用進行推理是沒有意義的。


附帶說明一下,地址0與NULL並不相同,並且不一定表示空指針。 NULL是一個空指針常量,而不是地址,其整數值為0(void*)0 當將NULL分配給任何類型的指針時,它將創建一個空指針。 空指針可以包含任何內部表示形式,例如地址0或其他某個值-C並未指定。

a [和b ]從未被初始化,因此它們可以具有任何值。 它們獲得的值恰好是在調用main之前,在main的堆棧幀的相應存儲位置中發生的值。 也就是說, ab函數作用域變量,因此它們駐留在函數的堆棧框架中。

在您的情況下, b得到了0x0,而a得到了一個非零值,這似乎是有效的,但不是 它可以指向程序物理地址空間中的任何地方 我們不知道那是哪里。 如果我們從中讀取,則它可能在程序的分配/有效/映射的地址空間之外,並且我們也會對此進行段錯誤。

或者,如果我們寫a指向的位置,則可能寫到任何位置。 因此,我們可能會在隨機位置破壞程序數據。 這可能不會立即生成異常,但是效果未知。 我們可能會覆蓋數據段中的值。

由於數據段中給定值的值不是靜態分配的,因此這可能會導致程序稍后生成不正確的結果。

或者,我們可能破壞了靜態分配的全局內存空間中另一個指針變量中包含的值。 稍后,取消引用指針可能[ 可能會]產生一個segfault

它甚至可能指向代碼段之類的受保護內存,這將再次生成段錯誤。

暫無
暫無

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

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