2013-12-22 89 views
1

我在Windows8上的Cygwin上運行以下程序。打印內存地址

#include<iostream> 
#include <stdio.h> 
using namespace std; 
int main(){ 
char c1 = 'a'; 
char c2 = 'b'; 
int i1 = 1; 
float l1 = 100; 
float f1 = 3.14; 
double d1 = 1.424; 
int i2; 
char c3; 
int i3; 
printf("&c1 -> %u\n", (unsigned long)&c1); 
printf("&c2 -> %u\n", (unsigned long)&c2); 
printf("&i1 -> %u\n", (unsigned long)&i1); 
printf("&l1 -> %u\n", (unsigned long)&l1); 
printf("&f1 -> %u\n", (unsigned long)&f1); 
printf("&d1 -> %u\n", (unsigned long)&d1); 
printf("&i2 -> %u\n", (unsigned long)&i2); 
printf("&c3 -> %u\n", (unsigned long)&c3); 
printf("&i3 -> %u\n", (unsigned long)&i3); 
} 

我的筆記本電腦在下面給出了結果。

$ ./a.exe 
&c1 -> 2337487 
&c2 -> 2337486 
&i1 -> 2337480 
&l1 -> 2337476 
&f1 -> 2337472 
&d1 -> 2337464 
&i2 -> 2337460 
&c3 -> 2337459 
&i3 -> 2337452 

據我所知,每個數據類型都有它自己的大小,並根據大小佔用的存儲器地址。例如,在這種情況下,因爲char類型只有1個字節大小,所以變量c1佔用1個存儲器地址(2337487),並且下一個變量c2從地址2337486開始。然而,我很困惑,因爲i1從2337480開始。如果c2也是char類型的變量,它不應該只佔用一個地址嗎?而i1從2337485開始?

我想這與編譯器有關,但不明白它是如何工作的。誰能給我一些建議?

+0

編譯器傾向於在內存對齊的地址放置可變地址,這可能需要較少的操作來訪問或處理某個值。 –

+0

另外,請注意,這些實際上是從下到上算的。所以'c2'只是來自下一個變量'c1'的一個地址。因此,所有'int'都至少與列表中的下一個變量相距四個字節,'char'距離一個字節。我不太清楚編譯器如何分配內存來知道它們爲什麼順序相反。 – aelfric5578

+0

它們是堆棧分配的,這就是爲什麼它們是相反的。 – chbaker0

回答

-1

這是一個編譯器優化:當分配的內存不是一個實體塊時,速度更快。

2

這是因爲數據結構對齊。

例如,當計算機的字大小爲4個字節(一個字節表示大多數機器上的8位,但在某些系統上可能不同)時,要讀取的數據應位於內存偏移量,該偏移量爲4.如果情況並非如此,例如數據從第14個字節開始,而不是從第16個字節開始,然後計算機必須讀取兩個4字節的塊並在讀取請求的數據之前進行一些計算,否則可能會產生對齊錯誤。即使先前的數據結構在第13個字節結束,下一個數據結構應該從第16個字節開始。在兩個數據結構之間插入兩個填充字節,以便將下一個數據結構與第16個字節對齊。