2017-09-04 105 views
-7

我得到了一個令人驚訝的觀察,下面的代碼越來越分段錯誤常量值賦值給整型指針在C工作對於這種情況

#include<stdio.h> 
void main() { 
    int *i; 
    *i = 100; 
    printf("%u\n",i); 
    printf("%d\n",*i); 
} 

但不是下面的一個。

#include<stdio.h> 
void main() { 
    char* str; 
    int *i; 
    *i=100; 
    str = "Hello"; 
    printf("%u\n",i); 
    printf("%s %d\n",str,*i); 
} 

有人可以解釋這種行爲嗎?我正在使用gcc。

+3

UB͏͏͏͏͏͏͏͏͏͏͏͏͏ – Bathsheba

+3

這是未定義的行爲,有沒有推理它 – stackptr

+0

是嗎?即使我這樣想,我也跑了好幾次,但每次都得到了正確的答案。那時我在這裏舉起它?真的是這樣嗎? – user3345621

回答

1

首先,均爲的片段導致undefined behavior,因爲未初始化指針i取消引用。

在第一種情況下,您試圖取消引用未初始化的指針i,這是未定義的行爲。

你做

*i = 100; 

但認爲,在哪裏呢i點?可能是某些內存位置不能從進程訪問,所以它是無效的內存訪問。這觸發了UB。

同樣在第二個片段中。

但是,如果您從第二個片段中刪除了i的使用情況,則它將會正常。

在建議的更改之後,在第二個片段中,您將字符串文本的起始地址存儲到指針變量中,即分配它。所以,這非常好。

對於如下語句

str = "Hello"; 

defererencing str這裏,而是分配一個指針值str,這是完全正常的。


這就是說,

  • 根據C標準,對於託管環境,void main()是不是符合簽名,您必須使用int main(void),至少。
  • printf("%u\n",i);這樣的聲明也會以自己的方式調用未定義的行爲。如果您想要打印指針,則必須使用%p格式說明符並將參數轉換爲void*
+1

在第二個片段中,他仍在使用內存未初始化的'i'變量 – stackptr

+0

@J ... S對,讓我重新解釋一下答案。 –

+0

第二種情況下,我工作,這就是問題.. – user3345621

0

由於以下原因,您的兩個程序都會導致未定義的行爲。所以不會得到正確的結果。

1)解引用未初始化的指針*i = 100;是未定義的行爲。在你的兩個例子中,在初始化它之前,你需要提取指針i。因此,首先使用&運算符初始化指針,然後在代碼中使用它。

2)使用無符號轉換說明符打印指針值。您應該使用%p

0

i尚未初始化爲指向任何內存位置,因此它不是有效的指針值。試圖通過無效指針寫入導致未定義的行爲,這意味着結果可能是任何東西 - 您的代碼可能會徹底崩潰,它可能會破壞數據,可能會出現亂碼,或者它可能看起來沒有問題。