地址存放与内存对齐:
关于栈的内存地址到底是怎么存放的呢,cywin下写了段代码测试:
1: $ cat cinputoutputadd.C
2: #include "stdio.h"
3:
4: int main (){
5: int a = 0;
6: char b;
7: int c = 0;
8: int d = 0;
9: printf("address of a is 0x%08x\n", &a);
10: printf("address of b is 0x%08x\n", &b);
11: printf("address of c is 0x%08x\n", &c);
12: printf("address of d is 0x%08x\n", &d);
13: printf("\n");
14: }
15:
输出如下:
1: $ ./a.exe
2: address of a is 0x0022ac5c
3: address of b is 0x0022ac5b
4: address of c is 0x0022ac54
5: address of d is 0x0022ac50
结论:
1. 之前只听说栈是向低地址扩展的,什么是向低地址扩展,是说后定义的变量地址一定小于先定义的地址吗?然后又是先进后出,是说先进去(定义的)的地址最低?从程序的结果来看a先定义了,但是地址最高。貌似是矛盾的。求高手解释。
2. 但从结果来判断,我理解a占用5c/5d/5e/5f, b占用5b,5a/59/58被填充,c占用54/55/56/57, d占用50/51/52/53, 占用字节向高地址方向扩展,填充字节在低地址方向。
内存覆盖:
然后来看下面的一段摘自 C Traps and pitfalls的程序:
#include "stdio.h" int main (){ char h; int a = 0; char c; printf("add of h is 0x%08x. \n", &h); printf("add of a is 0x%08x. \n", &a); printf("add of c is 0x%08x. \n", &c); while (a < 5){ scanf("%d", &c); printf("%d ", a); a++; } printf("\n"); }
变量h纯粹是为了搞清楚a的起始地址加的,结果如下:
关于地址,跟上一段代码一致,先定义的h地址最高,占一位。后面的a因为要占四字节,所以h会(向低字节)填充3个字节5c/d/e,h本身占用5f,a占用58/59/5a/5b,c占用57。现在来说下后面的输出,因为scanf以int型(4字节)向c保存用户输入的值,而c本身为char型,只占1字节。所以当输入的数字超过一个字节,即FF时,会向下覆盖a所占用的字节,覆盖时也有规律,超出的部分从高字节截断,比如256,十六进制为100,最高位1被截断填入a的低字节,即58,而58本身的值将被覆盖。这也就是为什么输入0~255,显示1,输入256~512显示2。如果输入的值为1024,十六进制为400,则a++后不满足循环条件a<5,程序结束。