当前位置:编程学习 > 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之前分配空间。
虽然可以测试,但是我不能够确定在其他情况下是否正确。

 

 

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,