该篇博客是自己学习的总结,如果有哪里理解的不对的地方,希望大家可以指点。

一、C内存空间分布图

二、各内存区域详解

1.代码区(.text): 该区域主要存放二进制可执行文件。

2.数据区(.data): 数据区可详细分为三块区域,分别是只读数据区、初始化数据区、未初始化数据区。

1). 只读数据区(.ordata) : 顾名思义,这个区域存放的是一些常量,包括字符串常量、const修饰的全局变量;

注意一: 字符串常量都是存储在只读数据区的。看下面一个例子,

 #include <stdio.h>

 int main(void)
{
char str[] = "I Love CHINA"; printf("the address of array: %p\n", str);
printg("the address of string: %p\n", "I Love CHINA"); str[] = 'W';
printf("%s\n", str); return ;
}

调试结构为:

the address of array: 0xbfa5052f
the address of string: 0x80485f5
W Love CHINA

看到这里可能就迷糊了,上面不是说字符串常量都存放在只读数据区吗?其实原因是这样的,当我们用字符串初始化字符数组时,是先将字符串字面量存储在只读数据区,当调用该初始化所在函数时,会将在数据区的数据拷贝一份到当前数组,当前运行的程序中就有两个''I Love CHINA'';我们改变了的其实是赋值到字符数组str所对应的在栈中的空间的值,而存放在数据区的字符串常量并没有改变。

注意二: 而const修饰的局部变量还是像普通的局部变量一样存放在栈中,只是不能显式的改变该变量。

2). 初始化数据区(.rwdata): 该区域用来存放初始化不为0的全局变量和static修饰的局部变量。

3). 未初始化数据区(.bss): 与初始化数据区类似,但是它存放的是初始化为0、未初始化的全局变量和static修饰的局部变量。这样做的目的主要是为了减少可执行二进制文件占用的存储空间,特别是在一些嵌入式设备中显得尤其重要。如下图,

 #include <stdio.h>

 int arr[] = {};

 int main(void)
{
printf("hello world\n"); return ;
}

 #include <stdio.h>

 int arr[] = {};

 int main(void)
{
printf("hello world\n"); return ;
}

3. 栈: 栈存放的是程序中的局部变量,  当然函数形参、返回值也都存储在栈中。栈是由系统自动管理,变量的出栈入栈操作都由系统通过移动栈顶指针来完成来完成,并不是真正的清除变量,所以当我们使用局部变量之前一定要给它赋值,否则就是一个不确定的值。

4.堆: 堆空间解决了自动分配不灵活,对内存造成浪费等问题。可以通过malloc函数申请所需大小的空间,注意这块空间申请了之后会一直存在,所以一定要和free一起使用,等用完之后马上释放,否则会造成内存泄漏,严重会导致程序停止运行。我们使用mallco函数带来方便灵活的同时,也带来了内存碎片的问题,所以当要求程序长时间运行时,必不可免的就要解决malloc带来的内存碎片问题。

C程序运行时的内存分布的更多相关文章

  1. c++程序运行时的内存分配《转》

    C++中,内存分为5个区:堆.栈.自由存储区.全局/静态存储区和常量存储区. 1.栈:是由编译器在需要时自动分配,不需要时自动清除的变量存储区.通常存放局部变量.函数参数等. 2.堆:是由new分配的 ...

  2. 实例分析C程序运行时的内存结构

      先验知识 静态变量存储在静态存储区,局部变量存储在动态存储区(栈),代码存放在代码区 寄存器,EBP指向栈底,ESP指向栈顶,EIP指向正在执行指令的下一条指令,三个寄存器中保存的都是地址,32位 ...

  3. Qt使用windows API获取程序运行时占用内存 good

    使用的是psapi.h中的GetProcessMemoryInfo函数,但是运行到该函数时就强制退出了. 后来,百度到原因是 原来Qt编译时加了-mthread,createprocess时要使的Ha ...

  4. [Java]程序运行时的内存分配

    本文出处:<Thinking in JAVA> 寄存器这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有限,所以寄存器根据需求进行分配.你不能直接控制 ...

  5. c++ 程序编译后运行时的内存分配

    程序编译后运行时的内存分配 太好的文章了,看到不得不转,转自:http://blog.sina.com.cn/s/blog_5420e0000101a0w1.html 一.编译时与运行时的内存情况 1 ...

  6. java程序运行时内存分配详解 (转)

    转自:http://www.tuicool.com/articles/uU77v2 一.  基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Ja ...

  7. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  8. Java程序运行时内存划分

    1.Java程序跨平台运行的原因 主要原因是:各种平台的JVM和字节码文件 Java源程序--具体平台的机器代码文件---被编译器翻译成平台无关的Class文件,又用特定JVM运行字节码文件,JVM在 ...

  9. 关于Class对象、类加载机制、虚拟机运行时的内存布局的全面解析和推测

    简介: 本文是对Java的类加载机制,Class对象,反射原理等相关概念的理解.验证和Java虚拟机中内存布局的一些推测.本文重点讲述了如何理解Class对象以及Class对象的作用. 欢迎探讨,如有 ...

随机推荐

  1. SQL FULL JOIN 关键字

    SQL FULL JOIN 关键字 只要其中某个表存在匹配,FULL JOIN 关键字就会返回行. FULL JOIN 关键字语法 SELECT column_name(s) FROM table_n ...

  2. java语言的特征

    运行时:反射与内省+派发机制: 额外的多态支持:注解: 语法改进:内部类与匿名类.匿名函数: 线程支持改进: 类加载机制? aop的支持: bean?

  3. 基于Spring Boot和Shiro的后台管理系统FEBS

    FEBS是一个简单高效的后台权限管理系统.项目基础框架采用全新的Java Web开发框架 —— Spring Boot 2.0.3,消除了繁杂的XML配置,使得二次开发更为简单:数据访问层采用Myba ...

  4. face alignment[Ordinary Procrustes Analysis]

    人脸识别,大致可以分为以下四个步骤: 人脸检测:从图片中准确定位到人脸,并以矩形框将其裁剪出来: 人脸矫正(对齐): 检测到的人脸,可能角度不是很正,需要使其对齐,比如旋转,缩放: 特征提取:对矫正后 ...

  5. 还是要习惯在linux环境下作Java开发

    要FQ 怎么在ubuntu上安装jdk 网址: https://www.youtube.com/watch?v=NZB3Iy7Lve4 需要网站:http://p.web.umkc.edu/pv6xc ...

  6. 完成了Coursera的一个机器学习课程

    终于完成了这个课程,从开始学习,到现在差不多过了一年的时间,中间由于一些原因耽搁了,最终还是完成了,记录一下!

  7. C# 相关面试试题简单的总结

    最近一个搞NET开发的朋友离职了,想让我给他找点关于NET的相关面试题,准备抱一下佛脚,迎接新的挑战. 我赶紧找到以前检索的各种宝典,试题,今天梳理一下关于NET的基础知识点. 1.面向对象语言的三大 ...

  8. Groovy语言学习--语法基础(4)

    语法基础到此就结束了,毕竟其和Java许多地方并无差别.groovy作为脚本,是为了能更好地随业务变化调整规则,我根据自己对规则的理解 通过一张图简单描述一个groovy脚本场景:由于货币膨胀,经济收 ...

  9. COMCMS 微进阶篇,从0开始部署到Centos 7.4

    言:上一篇,我们介绍了,如何本地调试和部署到windows服务器. 本篇,将带大家,从0到1,开始部署到Centos系统上... 经过测试,可以完美支持Centos.这也是.net core 跨平台的 ...

  10. 实现多个标签页之间通信的几种方法(sharedworker)

      效果图.gif prologue 之前在网上看到一个面试题:如何实现浏览器中多个标签页之间的通信.我目前想到的方法有三种:使用websocket协议.通过localstorage.以及使用html ...