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方式

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之外的数据类型,通常 按字对齐。如果例程中修改为
char a2='z',c='c';//填空
这时a2填空,但是c在i之前分配空间。
虽然可以测试,但是我不能够确定在其他情况下是否正确。

你可能感兴趣的:(C细节:内存方面)