2012-12-13 56 views
3

如果你有一個變量,就有一個與該變量相關聯的內存地址,並且在指針變量的情況下,該內存地址的「值」是對存儲地址的引用,該地址保存指針的實際數據指着。如果一個指針變量是在一個循環內聲明的,它是否與每個循環的相同內存地址相關聯?

所以,如果我有:

for (int x = 0; x < 2; x++) 
{ 
    char * a = (char*)malloc(20); 
    printf("%p\r\n", &a); 
    printf("%p\r\n", a); 
} 

輸出應該是這樣的:

00999999 
    04427310 
    00999999 
    0442ECF0 

正如你所看到的,第1和第3的內存地址仍然是指針變量相同在循環的每個過程中聲明,我的理解是,這是因爲前一個變量超出了範圍,下一個可用地址是相同的地址。

這個泛化是否可以擴展到循環中聲明的所有變量或者是否存在異常?

+1

沒有保證,但通常情況下,循環中聲明的變量通常在每次迭代中分配在相同位置,因爲它是編譯器最簡單的方法。 –

+0

變量沒有必要有一個內存地址 - 如果你沒有打印'&a','a'可能被保存在一個寄存器中(在這種情況下'x'最有可能在一個寄存器中)。 – molbdnilo

回答

3

這就是堆棧通常的工作方式。這與變量類型無關。當堆棧向下增長它可能看起來或多或少像這樣

<top> 
|     | 
+-----------------+ 
| argument1  | 
| argument2  | 
+-----------------+ 
| return address | 
+-----------------+ 
| saved register1 | 
| saved register2 | 
+-----------------+ 
| local variable1 | <- base register 
| local variable2 | 
| x    | 
| a    | 
|     | <- stack pointer 
<bottom> 

編譯器堆棧每個變量相對於一些基址寄存器上分配空間。當循環的範圍結束時,a的空間有效地變爲「空閒」並且可以被重用。

如果有後來的第二回路或其他一些嵌套範圍

for (int x = 0; x < 2; x++) 
{ 
    char * a = (char*)malloc(20); 
    printf("%p\r\n", &a); 
    printf("%p\r\n", a); 
} 
... 
for (int x = 0; x < 2; x++) 
{ 
    char * b = (char*)malloc(20); 
    printf("%p\r\n", &b); 
    printf("%p\r\n", b); 
} 

b可以重用以前a佔用的空間,因爲不再需要了它。這完全取決於編譯器如何優化堆棧上的空間。

這是至少編譯C語言的方式。當然還有其他的內存模型。

10

不,你不能一概而論,並且不能保證a(指針,不是它指向的內存)的內存在每次迭代中都是相同的。在這種情況下,內存被重用,它可能總是相同的,但是不能保證。

另請注意,您有內存泄漏。

相關問題