2010-06-26 78 views
0

如果我有這樣的代碼:內存中的變量是以C++存儲的變量嗎?

int e; 
int* f; 

int main() { 
    int a, b, c; 
    int* d; 
} 

在內存中存儲這些變量? 而且,定義全局變量有什麼問題(在這種情況下,像函數中的函數一樣)?

+4

閱讀此:http://www.gotw.ca/gotw/009.htm – 2010-06-26 17:12:57

+0

非常感謝您的鏈接! – Puyover 2010-06-26 17:33:09

回答

6

a,b,c和d將存在於堆棧中。如果你要創建一個int實例(使用malloc或new),那麼這個實例就會在堆上 - 但是名爲'd'的指針仍然會存在於堆棧中。

E和F在應用程序的內存空間分配的空間,在所謂的「數據段」 - 看到:

http://en.wikipedia.org/wiki/Data_segment

你還問到堆棧大小:那年代由編譯器配置,在這裏看到:

http://msdn.microsoft.com/en-us/library/tdkhxaks(VS.71).aspx

+0

噢,謝謝。非常有用的關於數據段的信息!關於堆棧大小謝謝,我現在更清楚:) – Puyover 2010-06-26 17:21:25

+0

使用任何優化編譯器,位於堆棧上的本地機器是一種可能的事情。從概念上說,他們都在籌備中,但大多數情況下這不會反映現實。 – 2010-06-27 02:40:38

+0

同意,爲了做得更多,他們將被轉移到註冊表(http://en.wikipedia.org/wiki/Processor_register)。但問'在哪裏分配局部變量'的答案是'堆棧':) – 2010-06-27 08:35:35

3

你爲什麼認爲這很重要?請注意,在現代C++中,擁有局部指針變量非常罕見。

在典型的系統上,a,b,c和d將存在於堆棧中。但是這是一個實現細節,語言標準沒有具體說明這一點。

+0

有什麼辦法,我可以知道標準PC中堆棧的大小是多少? – Puyover 2010-06-26 17:12:02

+0

堆棧大小是線程特定的。 – 2010-06-26 17:13:00

+0

...並找出給定線程的堆棧大小是特定於操作系統的。在Windows中,您可以通過檢索線程信息塊(32位)或線程環境塊(64位)來獲取此信息。 – stinky472 2010-06-27 01:23:12

9

實際上並沒有關於變量在內存中放置的保證,只有行爲。

但在大多數(或許是全部)實際系統中,ef將在全球數據部分,而abcd在寄存器中的混合和調用堆棧上。 fd都可以指向內存中的任何位置(好吧,對於MMU來說,這並非完全正確,它們可以指向映射到進程中的內存子集中的任何位置)。

+0

謝謝。那麼我可以根據需要定義許多全局變量,而不會產生性能問題/空間? – Puyover 2010-06-26 17:14:52

+4

@Puy:你肯定會遇到許多全局變量的設計問題。 – fredoverflow 2010-06-26 17:20:40

+0

你可以有很多全局變量,但是所有靜態分配的變量都必須被初始化,這會減慢程序的啓動速度。它可能不足以注意到。正如Fred所說,儘管使用大量全局變量會使程序難以維護,所以不建議這樣做。更好的做法是不需要外部鏈接的文件範圍變量,這可以使用C++中的無名稱命名空間或C中的static關鍵字(不推薦用於C++)完成,並且不會像全局變量那樣容易地導致意大利麪條代碼。 – 2010-06-27 02:38:56

1

重點是變量的範圍,它定義了它們的生命週期。主程序的變量外觀將在您的程序期間可用。 main()函數的持續時間內main中的變量將可用。

實際上,函數範圍變量通常在堆棧上分配,而全局變量在堆上分配,但這是一個實現細節。

全局變量的主要問題是控制訪問,他們可能很難在多線程程序中使用。

編輯:正如@FredOverflow指出下面,全局通常分配在加載可執行映像時設置的數據區域。

+0

我很確定全局變量不是從堆中分配的,而是從數據段中分配的。 – fredoverflow 2010-06-26 17:17:37

+0

@Fred - 你是對的。我的思維跟不上我的打字! – mdma 2010-06-26 17:56:50

3

通常,a,b,c,d *將在程序堆棧中定義,儘管C++ ISO標準沒有指定應定義變量的位置。

對於第二個問題,全局變量的問題是他們沒有保護。對於依賴於全局變量的簡單腳本/應用程序來說可能沒有問題,但是在庫和更復雜的代碼中,它會產生一個潛在的問題:任何代碼都可以隨時更改全局變量的值,留下任何依賴全局變量的代碼一個不希望的狀態。

此外,由於變量位於全局範圍內,因此如果您使用任何其他定義具有相同名稱的全局變量的代碼,那麼它們將面臨潛在的命名衝突。