码迷,mamicode.com
首页 > 其他好文 > 详细

C程序存储结构

时间:2018-10-24 15:42:03      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:内存   info   str   动态申请   .com   平台   html   变量   静态   

使用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\n", &i);
  printf("栈区-变量地址 p:%p\n", &p);
  printf("栈区-变量地址 str:%p\n", str);
  printf("栈区-变量地址 q:%p\n", &q);
  printf("堆区-动态申请 p: %p\n", p);
  printf("堆区-动态申请 p2: %p\n", p2);
  printf("全局外部有初值 k1: %p\n", &k1);
  printf("全局外部无初值 k2: %p\n", &k2);
  printf("静态外部有初值 k3: %p\n", &k3);
  printf("静态外部无初值 k4: %p\n", &k4);
  printf("内静态有初值 m1: %p\n", &m1);
  printf("内静态无初值 m2: %p\n", &m2);
  printf("文字常量地址 : %p, %s\n", q, q);
  printf("程序区地址 : %p\n", &main);
  return 0;
}

 

运行结果:

技术分享图片

 

分析:

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

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

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

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

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

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

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

 

总结如下图所示:

技术分享图片

 

 

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

C程序存储结构

标签:内存   info   str   动态申请   .com   平台   html   变量   静态   

原文地址:https://www.cnblogs.com/mobius2018/p/9842785.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!