数据在内存中的存储(栈的数据存储分布)

来源:互联网 发布:php新闻发布系统coon 编辑:程序博客网 时间:2024/06/05 18:41

数据在内存中的存储(栈的数据存储分布)

数据在内存中存储,采用大小端模式,内IA-32平台下,栈向下存储,先申请空间的变量存于栈的高地址中,后申请的空间位于栈的末端(低地址)空间中,下面用一些示例来进行说明(以下示例在VC6.0环境下编译和调试):

1,函数中的变量
函数中的变量,先申请的函数在内存的高地址,后申请的函数在内存的低地址,我们建立一个工程,控制台应用程序,编写如下代码:
void main()
{
 int i;
 int j;
 int k;
 char c;
 float f;
 printf("i:%X\n",&i);
 printf("j:%X\n",&j);
 printf("k:%X\n",&k);
 printf("c:%X\n",&c);
 printf("f:%X\n",&f);
}
运行结果:
 i:12FF7C
 j:12FF78
 k:12FF74
 c:12FF70
 f:12FF6C
可以知道,变量i的地址为:0x0012ff7c
          变量j的地址为:0x0012ff78
          变量k的地址为:0x0012ff74
          变量c的地址为:0x0012ff70
          变量f的地址为:0x0012ff6c

我们在函数体中先定义的变量i,i的地址在这5个变量中是最高的,和变量j的地址值差4字节,首先,字节长度来看,i,j,k,f都是4字节长度,c为1字节长度,在空间申请时,根据4字节做字节对齐,内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7E             │
├┄┄┄┄┄┄┄┄   i  ┄┤
│ 0x0012FF7D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7C             │ i的首地址:0x0012FF7C
├────────────┤
│ 0x0012FF7B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7A             │
├┄┄┄┄┄┄┄┄   j  ┄┤
│ 0x0012FF79             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF78             │ j的首地址:0x0012FF78
├────────────┤
│ 0x0012FF77             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF76             │
├┄┄┄┄┄┄┄┄   k  ┄┤
│ 0x0012FF75             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF74             │ k的首地址:0x0012FF74
├────────────┤
│ 0x0012FF73      null   │
├────────────┤
│ 0x0012FF72      null   │
├────────────┤
│ 0x0012FF71      null   │
├────────────┤
│ 0x0012FF70        c    │ c的首地址:0x0012FF70
├────────────┤
│ 0x0012FF6F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6E             │
├┄┄┄┄┄┄┄┄   f  ┄┤
│ 0x0012FF6D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6C             │ f的首地址:0x0012FF6C
├────────────┤
│                        │
│………   低地址   ………│


2,复杂数据类型--数组
在数组中的数据存储的模型与函数体中变量的存储类似,但是存储的方式相反,建立工程,编写如下代码,查看数组数据的地址:
void main()
{
 char c=0;
 int a[3]={0};
 double d=0;

 printf("%x\n",&c);
 printf("%x\n",&a[0]);
 printf("%x\n",&a[1]);
 printf("%x\n",&a[2]);
 printf("%x\n",&d);
}
运行结果如下:
 c:12ff7c
 a[0]:12ff70
 a[1]:12ff74
 a[2]:12ff78
 d:12ff68
可以知道,变量c的地址:0x0012FF7C 
          数组元素a[0]的地址:0x0012FF70
          数组元素a[1]的地址:0x0012FF74
          数组元素a[2]的地址:0x0012FF78
          变量d的地址:0x0012FF68
数组元素在内存中根据数组的大小申请空间,然后根据数组中的元素进行空间的分配,数组的最后一个元素存储在高地址,数组的第一个元素存储在低地址,内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F      null   │
├────────────┤
│ 0x0012FF7E      null   │
├────────────┤
│ 0x0012FF7D      null   │
├────────────┤
│ 0x0012FF7C        c    │ c的首地址:0x0012FF7C
├────────────┤─────────────────────┐
│ 0x0012FF7B             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF7A             │                                          │
├┄┄┄┄┄┄┄┄ a[2] ┄┤                                          │
│ 0x0012FF79             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF78             │ a[2]的首地址:0x0012FF78                 │
├────────────┤                                          │
│ 0x0012FF77             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF76             │                             数组a[3] 的内存空间
├┄┄┄┄┄┄┄┄ a[1] ┄┤                                          │
│ 0x0012FF75             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF74             │ a[1]的首地址:0x0012FF74                 │
├────────────┤                                          │
│ 0x0012FF73             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF72             │                                          │
├┄┄┄┄┄┄┄┄ a[0] ┄┤                                          │
│ 0x0012FF71             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF70             │ a[0]的首地址:0x0012FF70                 │
├────────────┤─────────────────────┘
│ 0x0012FF6F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6E             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6C             │
├┄┄┄┄┄┄┄┄   d  ┄┤
│ 0x0012FF6B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6A             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF69             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF68             │ d的首地址:0x0012FF68
├────────────┤
│                        │
│………   低地址   ………│


3,复杂数据类型--结构体

结构体在内存中的存储方式和函数体相反,与数组类似,结构体内最后定义的数据存储在高地址中,按下面的代码进行验证:
typedef struct SS
{
 int i;
 char a;
 short s[3];
 int b;
}SS;
void main()
{
 int i=0;
 SS s={0};
 int j=0;
 printf("i:%x\n",&i);
 printf("s:%x\n",&s);
 printf("s.i:%x\n",&s.i);
 printf("s.a:%x\n",&s.a);
 printf("s.s[0]:%x\n",&s.s[0]);
 printf("s.s[1]:%x\n",&s.s[1]);
 printf("s.s[2]:%x\n",&s.s[2]);
 printf("s.b:%x\n",&s.b);
 printf("j:%x\n",&j);
}
运行结果如下:
 i:12ff7c
 s:12ff6c
 s.i:12ff6c
 s.a:12ff70
 s.s[0]:12ff72
 s.s[1]:12ff74
 s.s[2]:12ff76
 s.b:12ff78
 j:12ff68
可以知道,变量i的地址:0x0012FF7C
          结构体s的首地址:0x0012FF6C
          结构体s的变量i的地址:0x0012FF6C
          结构体s的变量a的地址:0x0012FF70
          结构体s的变量s[0]的地址:0x0012FF72
          结构体s的变量s[1]的地址:0x0012FF74
          结构体s的变量s[2]的地址:0x0012FF76
          结构体s的变量s.b的地址:0x0012FF78
          变量j的地址:0x0012FF68

内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F              │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7E             │
├┄┄┄┄┄┄┄┄   i  ┄┤
│ 0x0012FF7D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7C             │ i的首地址:0x0012FF7C
├────────────┤────────────────────┐
│ 0x0012FF7B             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                    │
│ 0x0012FF7A             │                    │
├┄┄┄┄┄┄┄┄  s.b ┄┤                    │
│ 0x0012FF79             │                    │
├┄┄┄┄┄┄┄┄      ┄┤                    │
│ 0x0012FF78             │ s.b的首地址:0x0012FF78        │
├────────────┤                    │
│ 0x0012FF77             │                    │
├┄┄┄┄┄┄┄┄s.s[2]┄┤                    │
│ 0x0012FF76             │ s.s[2]的首地址:0x0012FF76        │
├────────────┤                                        │
│ 0x0012FF75             │                                        │
├┄┄┄┄┄┄┄┄s.s[1]┄┤                                        │
│ 0x0012FF74             │ s.s[1]的首地址:0x0012FF74             │
├────────────┤                                        │
│ 0x0012FF73             │                              结构体s的内存空间分配
├┄┄┄┄┄┄┄┄s.s[0]┄┤                                        │
│ 0x0012FF72             │ s.s[0]的首地址:0x0012FF72             │
├────────────┤                                        │
│ 0x0012FF71      null   │                                        │
├────────────┤                                        │
│ 0x0012FF70      s.a    │ s.a的首地址:0x0012FF70                │
├────────────┤                                        │
│ 0x0012FF6F             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                                        │
│ 0x0012FF6E             │                                        │
├┄┄┄┄┄┄┄┄ s.i  ┄┤                                        │
│ 0x0012FF6D             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                                        │
│ 0x0012FF6C             │  结构体s(s.i)的首地址:0x0012FF6C      │
├────────────┤────────────────────┘
│ 0x0012FF6B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6A             │
├┄┄┄┄┄┄┄┄  d   ┄┤
│ 0x0012FF69             │
├┄┄┄┄┄┄┄┄      ┄┤

数据在内存中的存储(栈的数据存储分布)

数据在内存中存储,采用大小端模式,内IA-32平台下,栈向下存储,先申请空间的变量存于栈的高地址中,后申请的空间位于栈的末端(低地址)空间中,下面用一些示例来进行说明(以下示例在VC6.0环境下编译和调试):

1,函数中的变量
函数中的变量,先申请的函数在内存的高地址,后申请的函数在内存的低地址,我们建立一个工程,控制台应用程序,编写如下代码:
void main()
{
 int i;
 int j;
 int k;
 char c;
 float f;
 printf("i:%X\n",&i);
 printf("j:%X\n",&j);
 printf("k:%X\n",&k);
 printf("c:%X\n",&c);
 printf("f:%X\n",&f);
}
运行结果:
 i:12FF7C
 j:12FF78
 k:12FF74
 c:12FF70
 f:12FF6C
可以知道,变量i的地址为:0x0012ff7c
          变量j的地址为:0x0012ff78
          变量k的地址为:0x0012ff74
          变量c的地址为:0x0012ff70
          变量f的地址为:0x0012ff6c

我们在函数体中先定义的变量i,i的地址在这5个变量中是最高的,和变量j的地址值差4字节,首先,字节长度来看,i,j,k,f都是4字节长度,c为1字节长度,在空间申请时,根据4字节做字节对齐,内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7E             │
├┄┄┄┄┄┄┄┄   i  ┄┤
│ 0x0012FF7D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7C             │ i的首地址:0x0012FF7C
├────────────┤
│ 0x0012FF7B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7A             │
├┄┄┄┄┄┄┄┄   j  ┄┤
│ 0x0012FF79             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF78             │ j的首地址:0x0012FF78
├────────────┤
│ 0x0012FF77             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF76             │
├┄┄┄┄┄┄┄┄   k  ┄┤
│ 0x0012FF75             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF74             │ k的首地址:0x0012FF74
├────────────┤
│ 0x0012FF73      null   │
├────────────┤
│ 0x0012FF72      null   │
├────────────┤
│ 0x0012FF71      null   │
├────────────┤
│ 0x0012FF70        c    │ c的首地址:0x0012FF70
├────────────┤
│ 0x0012FF6F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6E             │
├┄┄┄┄┄┄┄┄   f  ┄┤
│ 0x0012FF6D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6C             │ f的首地址:0x0012FF6C
├────────────┤
│                        │
│………   低地址   ………│


2,复杂数据类型--数组
在数组中的数据存储的模型与函数体中变量的存储类似,但是存储的方式相反,建立工程,编写如下代码,查看数组数据的地址:
void main()
{
 char c=0;
 int a[3]={0};
 double d=0;

 printf("%x\n",&c);
 printf("%x\n",&a[0]);
 printf("%x\n",&a[1]);
 printf("%x\n",&a[2]);
 printf("%x\n",&d);
}
运行结果如下:
 c:12ff7c
 a[0]:12ff70
 a[1]:12ff74
 a[2]:12ff78
 d:12ff68
可以知道,变量c的地址:0x0012FF7C 
          数组元素a[0]的地址:0x0012FF70
          数组元素a[1]的地址:0x0012FF74
          数组元素a[2]的地址:0x0012FF78
          变量d的地址:0x0012FF68
数组元素在内存中根据数组的大小申请空间,然后根据数组中的元素进行空间的分配,数组的最后一个元素存储在高地址,数组的第一个元素存储在低地址,内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F      null   │
├────────────┤
│ 0x0012FF7E      null   │
├────────────┤
│ 0x0012FF7D      null   │
├────────────┤
│ 0x0012FF7C        c    │ c的首地址:0x0012FF7C
├────────────┤─────────────────────┐
│ 0x0012FF7B             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF7A             │                                          │
├┄┄┄┄┄┄┄┄ a[2] ┄┤                                          │
│ 0x0012FF79             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF78             │ a[2]的首地址:0x0012FF78                 │
├────────────┤                                          │
│ 0x0012FF77             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF76             │                             数组a[3] 的内存空间
├┄┄┄┄┄┄┄┄ a[1] ┄┤                                          │
│ 0x0012FF75             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF74             │ a[1]的首地址:0x0012FF74                 │
├────────────┤                                          │
│ 0x0012FF73             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF72             │                                          │
├┄┄┄┄┄┄┄┄ a[0] ┄┤                                          │
│ 0x0012FF71             │                                          │
├┄┄┄┄┄┄┄┄      ┄┤                                          │
│ 0x0012FF70             │ a[0]的首地址:0x0012FF70                 │
├────────────┤─────────────────────┘
│ 0x0012FF6F             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6E             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6C             │
├┄┄┄┄┄┄┄┄   d  ┄┤
│ 0x0012FF6B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6A             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF69             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF68             │ d的首地址:0x0012FF68
├────────────┤
│                        │
│………   低地址   ………│


3,复杂数据类型--结构体

结构体在内存中的存储方式和函数体相反,与数组类似,结构体内最后定义的数据存储在高地址中,按下面的代码进行验证:
typedef struct SS
{
 int i;
 char a;
 short s[3];
 int b;
}SS;
void main()
{
 int i=0;
 SS s={0};
 int j=0;
 printf("i:%x\n",&i);
 printf("s:%x\n",&s);
 printf("s.i:%x\n",&s.i);
 printf("s.a:%x\n",&s.a);
 printf("s.s[0]:%x\n",&s.s[0]);
 printf("s.s[1]:%x\n",&s.s[1]);
 printf("s.s[2]:%x\n",&s.s[2]);
 printf("s.b:%x\n",&s.b);
 printf("j:%x\n",&j);
}
运行结果如下:
 i:12ff7c
 s:12ff6c
 s.i:12ff6c
 s.a:12ff70
 s.s[0]:12ff72
 s.s[1]:12ff74
 s.s[2]:12ff76
 s.b:12ff78
 j:12ff68
可以知道,变量i的地址:0x0012FF7C
          结构体s的首地址:0x0012FF6C
          结构体s的变量i的地址:0x0012FF6C
          结构体s的变量a的地址:0x0012FF70
          结构体s的变量s[0]的地址:0x0012FF72
          结构体s的变量s[1]的地址:0x0012FF74
          结构体s的变量s[2]的地址:0x0012FF76
          结构体s的变量s.b的地址:0x0012FF78
          变量j的地址:0x0012FF68

内存模型如下:

│………   高地址   ………│
├────────────┤
│ 0x0012FF7F              │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7E             │
├┄┄┄┄┄┄┄┄   i  ┄┤
│ 0x0012FF7D             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF7C             │ i的首地址:0x0012FF7C
├────────────┤────────────────────┐
│ 0x0012FF7B             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                    │
│ 0x0012FF7A             │                    │
├┄┄┄┄┄┄┄┄  s.b ┄┤                    │
│ 0x0012FF79             │                    │
├┄┄┄┄┄┄┄┄      ┄┤                    │
│ 0x0012FF78             │ s.b的首地址:0x0012FF78        │
├────────────┤                    │
│ 0x0012FF77             │                    │
├┄┄┄┄┄┄┄┄s.s[2]┄┤                    │
│ 0x0012FF76             │ s.s[2]的首地址:0x0012FF76        │
├────────────┤                                        │
│ 0x0012FF75             │                                        │
├┄┄┄┄┄┄┄┄s.s[1]┄┤                                        │
│ 0x0012FF74             │ s.s[1]的首地址:0x0012FF74             │
├────────────┤                                        │
│ 0x0012FF73             │                              结构体s的内存空间分配
├┄┄┄┄┄┄┄┄s.s[0]┄┤                                        │
│ 0x0012FF72             │ s.s[0]的首地址:0x0012FF72             │
├────────────┤                                        │
│ 0x0012FF71      null   │                                        │
├────────────┤                                        │
│ 0x0012FF70      s.a    │ s.a的首地址:0x0012FF70                │
├────────────┤                                        │
│ 0x0012FF6F             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                                        │
│ 0x0012FF6E             │                                        │
├┄┄┄┄┄┄┄┄ s.i  ┄┤                                        │
│ 0x0012FF6D             │                                        │
├┄┄┄┄┄┄┄┄      ┄┤                                        │
│ 0x0012FF6C             │  结构体s(s.i)的首地址:0x0012FF6C      │
├────────────┤────────────────────┘
│ 0x0012FF6B             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF6A             │
├┄┄┄┄┄┄┄┄  d   ┄┤
│ 0x0012FF69             │
├┄┄┄┄┄┄┄┄      ┄┤
│ 0x0012FF68             │  d的首地址:0x0012FF68
├────────────┤
│                        │
│………   低地址   ………│

 

 

 

 

 

 

 

 

  0x0012FF68             │  d的首地址:0x0012FF68
├────────────┤
│                        │
│………   低地址   ………│
0 0