美文网首页
内存分区

内存分区

作者: 闻道刘 | 来源:发表于2016-05-31 14:13 被阅读95次

http://blog.csdn.net/k346k346/article/details/45592329

导读

正确的理解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;

//编译器默认初始化为NULLvoidmain(){

int b;//栈

chars[] ="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++内存分区其实只有两个,即代码区和数据区。

相关文章

  • 操作系统-存储管理

    为什么内存要分区?分区有哪些类型? 内存分区是为了方便地支持多程序运行。分区管理分为固定分区和可变分区,固定分区是...

  • C++运算符重载实现(加号、左移、递增、赋值、关系运算符、函数调

    先来复习一下C++的内存分区问题~ C++内存分区 C++程序的内存分区可划分为四大内存分区:堆、栈、全局/静态存...

  • extern const static

    内存分区简介 | 内存分区 | 保存内容 | 是否可读写 | 是否手动释放 ...

  • linux运维之磁盘分区方案

    不同场景的分区: 1)普通分区形式: /boot 引导分区 256Mswap 交换分区 内存大于8G,给8G。内存...

  • linux系列10-交换分区Swap

    虚拟内存提升内存的容量,防止OOM(Out of Memory) -查看当前的交换分区 -增加交换分区基本分区,L...

  • 【String类】对象内存分配详解

    关于内存分区参见:Java内存详解 - 内存分区 本文重点描述String对象创建时的内存分配方式。 字符串常量池...

  • swap分区的创建及启动关闭

    Swap分区又称为交换分区,通常是在硬盘中预留一块分区作为swap交换分区,当系统内存出现不足时,系统会将空闲内存...

  • 内存管理

    目录一、内存分区 1、RAM和ROM 2、内存的五大分区二、内存管理 1、OC内存管理是指什么?OC内存管理的本质...

  • 内存分区

    原文章:https://blog.csdn.net/Damonvv/article/details/4715346...

  • 内存分区

    内存分区注意事项:1 在iOS中,堆区的内存是应用程序共享的,堆中的内存分配是系统负责的。2 系统使用一个链表来维...

网友评论

      本文标题:内存分区

      本文链接:https://www.haomeiwen.com/subject/kqwcdttx.html