程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> C細節:內存方面

C細節:內存方面

編輯:關於C

棧上分配空間時的地址數值從大向小變化。

當int i(一般的)被分配4字節空間,那麼變量所占內存空間的首地址——通常簡稱變量的地址,是最小的地址。假定32位的i分配為2000、2001、2002、2003地址,2000即為i的地址。很多書上畫示意圖的時候,把地址數值從小向大變化,以及將i的最高字節的地址作為首地址,是不是有點想當然。

例子:假定我們用int打包4個字符(位域處理),在big-endian機器上,在最低地址先存儲高字節數據。i由javz構成,則分別分配為2000(存放j)、2001(存放a)、2002、2003地址。小端(little-endian)時&i地址編號2000保存的是(z)。

big endian是指低地址存放最高有效字節(MSB),而little endian則是低地址存放最低有效字節(LSB)。


x86系列采用little endian方式

 

[cpp]
void headP(void){ 
    char j='J',a='a',v='v'/*,a2='z'*/;//對齊  
    printf("%p %p %p \n",&j,&a,&v); 
 
    unsigned int i=0; 
    i+=(j<<24)+(a<<16)+(v<<8); 
    printf("%p \n",&i); 
    char a2='z';//填空  
    i+=a2; 
 
    printf("%p \n",&a2); 
    char* cp=(char*)(&i); 
    printf("%p \n",(void*)(&cp)); 
    *(cp+3)='j'; 
    printf("%c%c%c%c\n",*cp,*(cp+1),*(cp+2),*(cp+3));//指向最後字節  
    printf("%c%c%c%c\n",*(cp+4),*(cp+5),*(cp+6),*(cp+7));    

void headP(void){
 char j='J',a='a',v='v'/*,a2='z'*/;//對齊
 printf("%p %p %p \n",&j,&a,&v);

 unsigned int i=0;
 i+=(j<<24)+(a<<16)+(v<<8);
 printf("%p \n",&i);
 char a2='z';//填空
 i+=a2;

 printf("%p \n",&a2);
 char* cp=(char*)(&i);
 printf("%p \n",(void*)(&cp));
 *(cp+3)='j';
 printf("%c%c%c%c\n",*cp,*(cp+1),*(cp+2),*(cp+3));//指向最後字節
 printf("%c%c%c%c\n",*(cp+4),*(cp+5),*(cp+6),*(cp+7)); 
}
輸出:

0012ff83 0012ff82 0012ff81
0012ff7c
0012ff80
0012ff78
zvaj
zvaJ


內存對齊和分配順序
例如例程中,大體按照程序文本順序分配空間;對於char之外的數據類型,通常按字對齊。如果例程中修改為
[cpp] view plaincopyprint?char a2='z',c='c';//填空 

char a2='z',c='c';//填空這時a2填空,但是c在i之前分配空間。
雖然可以測試,但是我不能夠確定在其他情況下是否正確。

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved