导读

正确的理解C/C++程序的内存分区,是合格程序猿的基本要求。

网络上流形两大版本内存分区,分别为:

1. 五大内存分区:堆、栈、全局/静态存储区、自由存储区和常量存储区。

2. 五大内存分区:堆、栈、全局/静态存储区、字符串常量区和代码区。

且不论以上两种分区孰是孰非,孰优孰劣,我认为具体的内存分区和编译器有很大关系,我想不同编译器对内存的划分都不尽相同,但也大同小异。

综合对比,查阅相关资料,提出自己对C/C++程序的内存分区的认识。可划分为四大内存分区:堆、栈、静态存储区和代码区。

堆区:

由程序猿手动申请,手动释放,若不手动释放,程序结束后由系统回收,生命周期是整个程序运行期间。使用malloc或者new进行堆的申请,堆的总大小为机器的虚拟内存的大小。

说明:new操作符本质上是使用了malloc进行内存的申请,new和malloc的区别如下:

(1)malloc是C语言中的函数,而new是C++中的操作符。

(2)malloc申请之后返回的类型是void*,而new返回的指针带有类型。

(3)malloc只负责内存的分配而不会调用类的构造函数,而new不仅会分配内存,而且会自动调用类的构造函数。

栈区:

由系统进行内存的管理。主要存放函数的参数以及局部变量。在函数完成执行,系统自行释放栈区内存,不需要用户管理。整个程序的栈区的大小可以在编译器中由用户自行设定,VS中默认的栈区大小为1M,可通过VS手动更改栈的大小。64bits的Linux默认栈大小为10MB,可通过ulimit -s临时修改。

静态存储区:

静态存储区内的变量在程序编译阶段已经分配好内存空间并初始化。这块内存在程序的整个运行期间都存在,它主要存放静态变量、全局变量和常量。

注意:

(1)这里不区分初始化和未初始化的数据区,是因为静态存储区内的变量若不显示初始化,则编译器会自动以默认的方式进行初始化,即静态存储区内不存在未初始化的变量。

(2)静态存储区内的常量分为常变量和字符串常量,一经初始化,不可修改。静态存储内的常变量是全局变量,与局部常变量不同,区别在于局部常变量存放于栈,实际可间接通过指针或者引用进行修改,而全局常变量存放于静态常量区则不可以间接修改。

(3)字符串常量存储在静态存储区的常量区,字符串常量的名称即为它本身,属于常变量。

(4)数据区的具体划分,有利于我们对于变量类型的理解。不同类型的变量存放的区域不同。后面将以实例代码说明这四种数据区中具体对应的变量。

代码区:

存放程序体的二进制代码。比如我们写的函数,都是在代码区的。

示例代码:

int a = 0;//静态全局变量区
char *p1; //编译器默认初始化为NULL
void main()
{
int b; //栈
char s[] = "abc";//栈
char *p2 = "123456";//123456在字符串常量区,p2在栈上
static int c =0; //c在静态变量区,0为文字常量,在代码区
const int d=0; //栈
static const int d;//静态常量区
p1 = (char *)malloc(10);//分配得来得10字节在堆区。
strcpy(p1, "123456"); //123456放在字符串常量区,编译器可能会将它与p2所指向的"123456"优化成一个地方
}

以上所有代码,编译成二进制后存放于代码区,文字常量存放于代码区,是不可寻址的。


总结

在理解C/C++内存分区时,常会碰到如下术语:数据区,堆,栈,静态存储区,静态区,常量区,常变量区,全局区,字符串常量区,静态常量区,静态变量区,文字常量区,代码区等等,初学者被搞得云里雾里。在这里,尝试捋清楚以上分区的关系。

数据区包括:堆,栈,静态存储区。

静态存储区包括:常量区(静态常量区),全局区(全局变量区)和静态变量区(静态区)。

常量区包括:字符串常量区和常变量区。

代码区:存放程序编译后的二进制代码,不可寻址区。

可以说,C/C++内存分区其实只有两个,即代码区和数据区。

本文难免出错,请同仁留言批评指正!谢谢


参考文献

[1]http://www.cnblogs.com/BreakMind/archive/2011/11/30/2268671.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

C/C++的四大内存分区 分类: C/C++ 2015-05-09 01:36 163人阅读 评论(0) 收藏的更多相关文章

  1. OC基础:内存(进阶):retain.copy.assign的实现原理 分类: ios学习 OC 2015-06-26 17:36 58人阅读 评论(0) 收藏

    遍历构造器的内存管理 a.遍历构造器方法内部使用autorelease释放对象 b.通过遍历构造器生成的对象.不用释放. 内存的管理总结 1.想占用某个对象的时候,要让它的引用计数器+1(retain ...

  2. OC基础:内存(内存管理) 分类: ios学习 OC 2015-06-25 16:50 73人阅读 评论(0) 收藏

    自动释放池: @autoreleasepool { } 内存管理机制       谁污染,谁治理 垃圾回收机制:gc(Garbage collection),由系统管理内存,开发人员不需要管理. OC ...

  3. 8大排序算法图文讲解 分类: B10_计算机基础 2014-08-18 15:36 243人阅读 评论(0) 收藏

    排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 常见的内部排序算法有:插入排序.希尔排序. ...

  4. c++map的用法 分类: POJ 2015-06-19 18:36 11人阅读 评论(0) 收藏

    c++map的用法 分类: 资料 2012-11-14 21:26 10573人阅读 评论(0) 收藏 举报 最全的c++map的用法 此文是复制来的0.0 1. map最基本的构造函数: map&l ...

  5. Mahout快速入门教程 分类: B10_计算机基础 2015-03-07 16:20 508人阅读 评论(0) 收藏

    Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现.分类.聚类等.Mahout最大的优点就是基于hadoop实现,把很多以前运行于单 ...

  6. 共享内存+互斥量实现linux进程间通信 分类: Linux C/C++ 2015-03-26 17:14 67人阅读 评论(0) 收藏

    一.共享内存简介 共享内存是进程间通信中高效方便的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针,两个进程可以对一块共享 ...

  7. OC基础知识总结 分类: ios学习 OC 2015-06-26 17:58 58人阅读 评论(0) 收藏

    //OC: Objective-C, 面向对象的C语言 //OC与C的区别 //1.OC是C的超集, C语言的所有语法都可以在OC中使用 //2.OC是面向对象 //3.OC是一门运行时语言 //4. ...

  8. 【C#小知识】C#中一些易混淆概念总结(六)---------解析里氏替换原则,虚方法 分类: C# 2014-02-08 01:53 1826人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 [C#小知识]C#中一些易混淆概念总结(二)--------构造函数,this关键字 ...

  9. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏

    目录: [C#小知识]C#中一些易混淆概念总结--------数据类型存储位置,方法调用,out和ref参数的使用 继上篇对一些C#概念问题进行细节的剖析以后,收获颇多.以前,读书的时候,一句话一掠而 ...

随机推荐

  1. 通过 Informix 系统表监控和优化数据库

    Informix 数据库系统字典表简介 Informix 数据库服务器运行时的状态信息是数据库管理员 DBA 进行系统监控和优化的必需信息来源.Informix 的状态信息在内部以 2 种方式存在,如 ...

  2. javasrcipt中的for in 循环

    function myFunction(){ var x;  //声明变量x: var txt="";  //声明变量txt并赋值为空: var person={fname:&qu ...

  3. UIScrollView 原理详解

    转载此文章原因:web页面在ipad的app中总是有橡皮筋效果,使用iscroll虽然能解决橡皮筋想过,但是滚动层内的元素事件都无法触发.故同安卓和ios一样使用后台解决...红色的为解决方案.. S ...

  4. Java Script

    一.JavaScript简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司 ...

  5. WPF自定义窗口基类

    WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...

  6. sqlserver中创建包含事务的存储过程

    什么是事务     事务时包含1条或多条语句的逻辑单元.事务中的语句是一个整体,要么一起提交,要么一起撤销.事务在提交前可以回滚,一旦提交就不能撤销修改了,是永久性的修改.   为什么使用事务     ...

  7. 1410. Crack

    http://acm.timus.ru/problem.aspx?space=1&num=1410 题目倒是不难,水题DP 就是题意理解起来有点困难,意思就是给你一段话,提取里面的单词 单词有 ...

  8. [Weekly] 2014.03.01-2014.03.08

    这周写过好多东西,虽然还没有完全弄明白线段树,但是progress还是有的! 不过有时候真的很想哭,因为自己的梦想连别人看看韩剧.无所事事还要分量轻,实在不明白政治课的Teamwork意义何在,花两分 ...

  9. Android Studio的一些快捷键

    以下这些也是百度的其他人整理的.后面有新的会加进来. AS的快捷键容易和QQ,微信等冲突,可以手动关掉或者修改其他软件的热键 Ctrl+G / Ctrl+Alt+Shift+G:查询变量或者函数或者类 ...

  10. 多个微信菜单都需要获取openId的时候如何处理回调页面的问题

    1.要建立一个特殊的页面处理这个逻辑 if (taskClassId == "6027") { Response.Redirect("./ProductAdvice.as ...