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

一、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. ansible-playbook 进行批量安装tomcat8

    ansible-playbook 进行安装tomcat操作 说明: get_url  中下载的内容直接到目的主机 安装的时候需要指定copy: no,说明需直接从目标主机进行安装包 [root@ans ...

  2. len()方法

    len() 方法返回对象(字符.列表.元组等)长度或项目个数 len()方法语法: len( 对象 )

  3. 三.js实例

    1.完成一个双色球,红球的自选效果 规则:1-33 用表格画出一个1到33的格子,点击一个自选按钮,将随机选中6个数字,每个表格对应的数字的背景就改为一个红球的效果 双色球.html <!DOC ...

  4. (二 -3) 天猫精灵接入Home Assistant-自动发现Mqtt设备--灯系列

    参考网站 1该mqtt光平台可以让您控制您的MQTT启用灯.它支持设置亮度,色温,效果,闪烁,开/关,RGB颜色,过渡,XY颜色和白色值. https://www.home-assistant.io/ ...

  5. 02 python初学 (数字运算 逻辑运算)

    运算: 5/2 -> 2.5 5//2 -> 2  取整 5%2 -> 1  取余 2**10 -> 1024 指数运算 逻辑运算符: and : 条件1 and 条件2 no ...

  6. wordpress数据表分析

    wordpress一共是有12个表的:|wp_commentmeta || wp_comments || wp_links || wp_options || wp_postmeta || wp_pos ...

  7. 【转】Java日志框架:logback详解

    为什么使用logback 记得前几年工作的时候,公司使用的日志框架还是log4j,大约从16年中到现在,不管是我参与的别人已经搭建好的项目还是我自己主导的项目,日志框架基本都换成了logback,总结 ...

  8. C# — 动态获取本地IP地址及可用端口

    1.在VS中动态获取本地IP地址,代码如下: 2.获取本机的可用端口以及已使用的端口:

  9. Mybatis学习总结(九)——查询缓存

    一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能.mybaits提供一级缓存和二级缓存. 1.一级缓存是sqlSession级别的缓存.在操作数据库时需要构造sqlSe ...

  10. 基于注解处理器开发自动生成getter和setter方法的插件

    昨天无意中,逛到了lombok的网站,并看到了首页的5分钟视频,视频中的作者只是在实体类中写了几个字段,就可以自动编译为含setter.getter.toString()等方法的class文件.看着挺 ...