【C】关于内存地址

地址存放与内存对齐:

关于栈的内存地址到底是怎么存放的呢,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,程序结束。

原文地址:https://www.cnblogs.com/dracohan/p/3010603.html