2016-06-28 37 views
-3

如果我有兩個變量a我b都是int,並且一個指針ptr指向& b。如果我們會像這樣增加ptr ++,它應該指向a,如果我沒有錯的話。我認爲這是可能的,因爲當編譯一個我在堆棧和B有4個字節小於A.但是當我在下一行打印那個指針時,我只能得到地址。 代碼:內存中的變量

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

int main(void) 
{ 
    int a = 52; 
    int b = 12; 


    int *ptr; 
    ptr = &b; 

    printf("%d\n",*ptr); 
    ptr++; 
    printf("\n%d",*ptr); 



    return 0; 
} 

但如果我把的printf( 「%d」,&一個);那麼最後的printf打印好並打印 碼的值:

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

int main(void) 
{ 
    int a = 52; 
    int b = 12; 

    printf("%d\n",&a); 
    int *ptr; 
    ptr = &b; 

    printf("%d\n",*ptr); 
    ptr++; 
    printf("\n%d",*ptr); 



    return 0; 
} 

有人能解釋我爲什麼出現這種情況? 圖片:

enter image description here

+6

您不能將指向一個對象的指針遞增指向另一個對象,除非這兩個對象是同一個數組的一部分。您的程序展示未定義的行爲。 – EOF

+0

我知道,關於數組,實際上他們正好落後於另外4個字節,並且他們將總是蜜蜂,只有當我使用更多的變量不同的類型,然後之間的空間不會相等。 – honeyPot

+0

您的第一個程序從不使用'a',因此編譯器正在優化內存分配和/或分配。第二個程序使用它,所以它得到內存分配。 – Barmar

回答

2

編譯器可以自由安排它在堆棧中選擇的任何順序的局部變量。事實上C標準甚至沒有提到堆棧。這是編譯器的實現細節。

添加看似不相關的代碼行可能會導致編譯器決定以不同於沒有附加代碼的順序將變量放置在堆棧上。所以在編寫代碼時你不能依賴這種行爲。這樣做是你經歷過的undefined behavior

此外,對不屬於同一數組的變量執行指針運算也是未定義的行爲。

-1

你不能保證ab變量是近記憶存儲在任何地方,這是普通的不安全的指針遞增,從一個嘗試「旅行」到另一個,和依靠結果。你正在做的事是陷入未定義行爲的領域,你不應該那樣做。

0

C11草案標準n1570:

6.5.2.4後綴增量和減量運算

[...]見添加劑運營商對於 討論和化合物分配關於約束條件,類型和轉換的信息以及操作對 指針的影響。[...]

6.5.6加法運算符

對於這些操作符的目的,一個指針到一個對象,它是不是一個 數組的元素的行爲相同的指針第一長度爲1的數組的元素,該對象的類型爲 作爲其元素類型。

[...]如果兩個指針 操作數和結果指向相同的數組對象的元素,或一個過去的陣列對象的最後 元件,評價不得產生溢出;否則, 行爲未定義。如果結果指向一個超過數組對象的最後一個元素,則不應將其作爲被評估的一元運算符的操作數使用 。

ptr = &b;ptr++;後,printf("\n%d",*ptr);提領ptr不確定的行爲