C程序存储结构

Posted mobius2018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C程序存储结构相关的知识,希望对你有一定的参考价值。

使用windows平台MinGW版本的GCC编译器,对以下代码片段进行了编译,探究各个变量在内存中的存储位置:

(不同的机器、不同的操作系统的GCC版本可能有差异,因此结论不具有普遍适用性,具体情况需要编译执行此代码自行分析)

 

代码片段:

#include <stdio.h>
#include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main()
{
  static int m1 = 2, m2;
  int i = 1;
  char *p, *p2;
  char str[10] = "hello";
  char *q = "hello";
  p = (char *)malloc(100);
  p2 = (char *)malloc(100);
  free(p);
  free(p2);
  printf("栈区-变量地址 i:%p ", &i);
  printf("栈区-变量地址 p:%p ", &p);
  printf("栈区-变量地址 str:%p ", str);
  printf("栈区-变量地址 q:%p ", &q);
  printf("堆区-动态申请 p: %p ", p);
  printf("堆区-动态申请 p2: %p ", p2);
  printf("全局外部有初值 k1: %p ", &k1);
  printf("全局外部无初值 k2: %p ", &k2);
  printf("静态外部有初值 k3: %p ", &k3);
  printf("静态外部无初值 k4: %p ", &k4);
  printf("内静态有初值 m1: %p ", &m1);
  printf("内静态无初值 m2: %p ", &m2);
  printf("文字常量地址 : %p, %s ", q, q);
  printf("程序区地址 : %p ", &main);
  return 0;
}

 

运行结果:

技术分享图片

 

分析:

(在保存程序之前编译器应该还要进行预处理进行宏替换等,因为没有详细读过《编译原理》,暂不讨论)

1. 编译器先保存程序内容,所以程序区在内存的地址最小;

2. 编译器优先保存已经赋值初始化的全局变量和静态变量:按照全局外部变量->静态外部变量->静态内部变量的顺序依次存储;

3. 编译器保存过已经赋值初始化的全局变量和静态变量后,开始处理并保存文字常量;

4. 编译器处理并保存文字常量后,开始保存没有赋初始值的全局变量和静态变量:按照静态外部变量->静态内部变量->全局外部变量的顺序依次存储;

5. 将方法的局部变量入栈(因为讨论变量,方法的地址指针暂不讨论)。因为栈的存储规律是后进先出,所以最后定义的变量先入栈,即存在较小的地址,所以也可以推出程序执行时的内存寻址是由低到高。

6. 最后将动态申请的变量按先进先出的顺序存入堆区。

 

总结如下图所示:

技术分享图片

 

 

源代码和上图右侧的文字来源:http://www.runoob.com/cprogramming/c-variables.html 的文章评论区,对代码片段增加了一个堆区的内存分配(char *p2),探讨堆内存的内存分配规律。

































以上是关于C程序存储结构的主要内容,如果未能解决你的问题,请参考以下文章

10. _____是存储在计算机内有结构的数据的集合。

C程序:从文件中读取矩阵数据,并显示出来,利用链式存储结构。

c/c++转化为XML存储????

数据结构-c语言内的内存分配

变量与存储空间及其存储结构

逻辑数据结构和存储数据结构