2015-06-10 101 views
2

我正面臨一個奇怪的問題。我有一個模塊,說x.c這是示例代碼段代碼:靜態全局變量的地址改變了嗎?

typedef struct lat {  
    int x; 
    int y; 
    int z; 
} lat; 

static lat x; 

static void populate(int x, int y, int z) { 
    lat *pLat = &x;   
    printf(" The value of pLat is %p \n", pLat); 

    pLat->x = x; 
    pLat->y = y; 
    pLat->z = z; 
} 

extern dump_report(void *pPayload) { 
    lat *pLat = &x;   
    printf(" The value of pLat is %p \n", pLat); 

    memcpy(pPayload, pLat, sizeof(lat)); 
} 

全局變量的地址是不同的(printf S),在這兩個功能呢? populate()在模塊內部被調用並給出正確的值,而dump_report()被從另一個模塊調用併產生全局變量和歸零值的錯誤地址。

有人可以讓我知道我是否做錯了什麼嗎?

+3

你是怎麼確定由'populate'打印的地址是正確的地址的? (提示:不是。) – hvd

+0

您是使用C或C++編譯器 - 您的代碼看起來像C,但您也使用C++標記過,我認爲這是不合理的。 –

回答

13

你掩蓋全局x與當地int x從你的函數定義:

static void populate(int x, int y, int z) 

只需重命名int x

+1

請注意,如果編譯器正在發佈適當的診斷信息,那麼爲不兼容類型的指針賦值'&x'將會出錯; C和C++都沒有這種自動轉換。 –

+0

那麼,「正確的診斷」允許警告,許多C編譯器確實只允許這樣的轉換,而不是一個錯誤。儘管如此,OP確實需要檢查任何生成的警告。 – hvd

4

局部變量優先於全局變量。所以你必須重命名你的int xstatic lat xenter image description here

而且我會建議你使用更好的編譯器。

1

全局靜態變量存儲在.BSS中,因爲它初始化爲零。但Local variable存儲在堆棧內存中。所以內存地址會有所不同。兩個變量都具有相同的名稱,但它們存儲在不同的存儲器中,因爲它們在編程上下文中不同。重命名變量將用於您的目的。

0

如果一個全局變量和本地變量名稱相同,那麼每次都局部變量優先於全局變量。