2012-08-14 341 views
2

我的問題是關於4GB可尋址系統的內存管理
char *p = NULL;
它是否佔用任何內存?
如果是這樣,在堆或棧中的位置和多少? 也告訴char **p=NULL;char * p = NULL需要內存?

+0

你的'p'聲明在哪裏?本地功能?功能之外? – AnT 2012-08-14 13:37:54

+0

@AndreyT它有什麼區別?如果是這樣告訴我。 – akash 2012-08-14 13:43:24

回答

8

在一個典型的32位系統上,它需要4個字節。

假設您的示例是某個函數中局部變量的定義,那些字節將從堆棧中獲取。雖然:

  • 如果該變量未在別處使用,編譯器可能會將其從生成的代碼中完全刪除;
  • 如果這個變量只用於本地,並且它的地址沒有被佔用,它可能被放入一個寄存器,所以它不會佔用「常規」的內存。

反之,如果它是一個全局變量(或,一般地,與靜態存儲持續時間一個變量),在大多數系統有存儲器的特殊區域(從堆棧和所謂的堆分離)用於他們。通常它只是在寫入時複製模式下直接從可執行映像映射的內存區域。所以這裏的4個字節都被佔用在這個特定的內存區域中,都在可執行文件的空間中。

這同樣適用於char **p,根據原則,從char *沒有理由變得更大或不同。


順便說一句,如果char * pchar ** p是聚合數據類型(通常爲struct)的一部分,它們乘坐空間來自任何地方的struct分配 - 如果struct變量是一個局部變量,它來自堆棧,如果它是在堆上動態分配malloc,如果它是全局的,它來自全局變量的特殊內存區域。請記住,在談論struct所用的空間時,有關填充的其他考慮因素髮揮作用。


請注意,所有這些都是對「典型」32位系統有效的注意事項;沒有什麼能阻止一些奇怪的架構,使char **大小不同於char *(儘管我沒有看到有任何理由這麼做)。不過,您也可以使用sizeof操作員進行直接檢查。就標準而言,我認爲對指針大小施加的唯一約束是任何指向數據的指針都可以在不丟失信息的情況下被轉換爲和從void *轉換(實際上,該標準並沒有提到過堆棧或寄存器)。另外,請記住,只要「可觀察行爲」與標準要求的內容一致,編譯器就可以做任何事情,因此標準規定的這些實現細節並沒有真正的保證,儘管更多細節可以在您正在使用的編譯器的文檔中找到。

+0

否則 - 它將位於堆棧上。 'char ** p'相同; – arrowd 2012-08-14 13:36:29

+0

如果它是動態分配的'struct'中的成員呢,它在堆棧上呢? – 2012-08-14 13:37:15

+0

@BinaryWorrier:它不能成爲動態分配的'struct'的成員,因爲不允許像OP那樣直接初始化它們。 – 2012-08-14 13:38:26

1

沒有上下文,你的變量p意願一般兩個版本佔據一個char*和一個char**分別記憶,這是自動(「堆棧」)或靜態(「全局」)存儲。所需的尺寸不大於void*(通常是一個機器字)的尺寸。

編譯器總是被允許表現爲「好像」這個變量存儲在內存中,但如果它可以直接替換它的值,它可以完全刪除變量。從這個意義上說,並不能保證你的C構造會產生任何特定的具體機器代碼。

0

指針只是一個可以容納地址的普通變量。無論變量的值是什麼,只要創建了一個char *變量,它都將使用內存。在32位系統上,指針的典型大小是32位,在64位機器上是64位。像intlong