2014-02-09 113 views
2

我編寫了這個程序來檢查本地變量和全局變量的地址。我讀到堆棧段存儲局部變量和數據段存儲全局變量。但是當我執行這個程序時,兩個變量的地址沒有太大的區別,這意味着它們必須在同一個段中。無法理解爲什麼會這樣..這裏是代碼和輸出 -本地和全局變量的地址

#include<stdio.h> 
    int *chr; 
    void main(){ 
     int *char1; 
     printf("global- %p \n local- %p",chr,char1); 
     chr=malloc(sizeof(int)); 
     char1=malloc(sizeof(int)); 
     printf("malloc_global = %p \n malloc_local = %p",chr,char1); 
    } 

輸出 -

global- (nil) 
local- (nil) 
malloc_global = 0x969010 
malloc_local = 0x969030 
+0

理解*任何*類型都可以。你不需要聲明指針。聲明'char foo;'並打印'printf(「%p」,&foo);''將打印'foo'的位置。 – ArjunShankar

+0

@ArjunShankar:使用'%p'轉換說明符打印的指針應該轉換爲與'void *'兼容的類型,如果它們不在。儘管在現代系統中很少見,但不同類型的指針可能具有不同的表示形式,並且傳遞與'void *'不兼容的類型以'%p'打印時具有C標準未定義的行爲。 –

+0

@EricPostpischil - 你是對的。我的意見最初意味着作爲對此問題的回答(與OP的「printf(」%p「)相反的早期(現已刪除)評論的補充,它建議將printf(」%p「,&chr) CHR)')。 – ArjunShankar

回答

4

我認爲你對變量和它們存儲的位置以及這些變量的內容感到困惑;當您選擇使用指針變量時會產生混淆,因此有兩個相關的地址(指針變量存儲的位置以及其內容)。

讓我們來看看發生了什麼。

chr是一個全球性的,在數據​​部分。 chr1是一個本地,並在堆棧段。

你是不是然而打印出其中chrchr1存儲,但chrchr1內容。作爲全球性保證初始化爲零的chr。作爲本地的chr1未定義。幸運的是,這只是零。然後您使用malloc分配內存,並將分配的地址分配給chrchr1malloc()分配在堆上並用於兩個分配,因此chrchr1包含類似的地址。再次,您打印這些變量的內容,而不是它們的地址(即存儲內容的位置)。要做後者,你需要:

printf ("global: %p \nlocal: %p\n", &chr, &char1); 

注意&運算符,它接受變量的地址。變量本身持有的內容是一個地址的事實是(爲此目的)不相關的;例如,它們可能是整數。

+0

+1'),用於指出OP的混淆。從指針的使用和OP的打印價值的嘗試可以清楚地看出,OP對指針的理解缺乏清晰度。 – ArjunShankar

2

嘗試打印出來的&chr&char1的值,而不是什麼他們的內容指向在。

malloc()從堆中分配存儲,並且這兩個變量都指向堆上的內存。

4

兩個變量的地址並沒有太大的區別,暗示他們必須在同一網段

正確的。它們是:兩者都指向堆地址,這是malloc從中分配存儲的地址。 Mitch指出,通過使用&chr&char1,您可以輸出指針的地址。這些可能會更加不同(或者不是;你的程序是微不足道的,也許編譯器仍然將它們貼在一起,即使它們在不同的部分)。

+0

我檢查了&char1和&chr,得到了這個 - 全局0x600990 local- 0x7fffa55aec88 malloc_global = 0x600990 malloc_local = 0x7fffa55aec88這是地址的一個很大的區別。請解釋這個 – Imdad

+1

@imdad當你通過'malloc'改變它的內容時,* pointer *的地址不會改變 - 爲什麼會這樣呢?指針本身分配在堆棧(或全局段)上。只有* pointee *地址纔會更改。 –

+1

@imdad'&chr'是全局變量的地址。 '&char1'是本地變量的地址。 'chr'和'char1'是變量的*內容*,它是'malloc'爲你分配的地址。由於'malloc'分配了這兩者,因此它們位於相同的內存區域('malloc'使用' – immibis