一个由C/C++编译的程序除了存放函数二进制代码的程序代码段(code段)外,数据占用的内存大致分为以下几个部分:

1、栈区(stack)
存放局部变量、函数参数、返回数据、返回地址等。系统自动分配释放,其操作方式类似于数据结构中的栈。
需要注意的有三点:
第一,退栈后销毁进栈时定义数据,请看下面这段。
char*fun(char *p)
{
  chartest[] = "hello";
  p =test;
  returnp;
}
//下面是某调用函数中的代码
char *a ="world";
printf("%s\n",fun(a));
输出的结果是什么?hello还是world?
test[]数组是局部变量,当所属函数被调用时,系统为之在栈区分配一段内存空间,存六个字符以及一些记录信息,test对应该段内存空间首地址,当一个参数即指针p传入时,将test的值赋给p,而当函数调用结束的时候,发生退栈操作,刚才分配的内存被“销毁”,即写入“垃圾信息”。所以调用的结果是:给参数赋给了一个栈区地址,该地址指向的内存空间里是一堆垃圾信息,所以输出结果既不是hello又不是world。
第二,正是由于栈“后进先出”的特点,所以函数调用的机制是借助栈区来完成的,而当我们进行大量频繁的调用操作时,系统将随之进行大量的进栈退栈操作,从而消耗时间资源,使得程序的执行效率下降。C语言解决的方法是使用宏来代替那些短小而被频繁调用的函数,而C++则是引入了内联函数机制。除此之外,还有就是提高编程技巧,注意细节,比如这段代码,for (i=0; i如果循环过程不改变fun()的取值的话,那么强烈建议将此代码调整为
temp =fun();
for (i=;i
{
  //***************
}
由于减少了每次循环中调用函数所造成的进栈退栈开销,所以执行效率将大大提高。需要类比的一个例子是循环嵌套,同样为了降低开销,建议在允许的情况下,将循环次数多的循环放在里面。
第三,由于系统为栈分配的空间很有限,一般只有1M(可以调整设置),如果申请的栈空间太大,将会出现栈溢出的错误。一次试验时,我用的机器上能分配的最大栈空间为1036084byte,也就是0.988M。所以当在栈区定义“大数据”时,一定要敏感。

2、堆区(heap)
堆:是在任何内存中动态和随机分配的内存的统称,也就是无序的,
由程序员通过malloc()函数(free释放),new操作符分配(delete/delete[]释放),若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表。
需要注意的有五点:
第一,分配后马上进行分配成功与否的验证。
第二,有分配必须有释放,否则将有可能造成内存泄露。遵循“谁分配谁释放”的原则。
第三,操作上,malloc和free对应,new和delete对应。另外,前者是库函数,使用时需要加载相应头文件,后者是C++中的关键字,是运算符,不需要加特别的头文件。
第四,运行效率没有栈高,而且大量频繁使用将造成更多的内存碎片。
第五,虽然free()函数的参数是指针,但它释放的是内存而不是指针,所以当执行完free()操作后,还应该将指针置空,以避免野指针问题。

3、全局区(静态区)(static)
存放全局变量、静态变量。程序结束后由系统释放。
C程序根据全局变量和静态变量有没有进行显式初始化,还将它们分为两个不同的区域,即BSS和DATA。据说这种区别在C++中已经没有了,而且编码规范要求我们在定义一个变量时,一定要同时对它进行初始化(尤其是一个指针,最好将它置为空),所以我们尽量还是在允许的情况下,遵守这一规范。另外需要特别说明的是,当没有进行显式初始化时,它们的值将被初始化为0。
当函数或外部变量的前面冠以static时,它们的可见范围将限定在所在文件内,程序中其他文件无法见到它们,我们可以用这个办法来有效避免命名冲突。而当一个局部变量被static修饰时,它的可见范围并没有修改,还是限定在函数内,但它的生存期将延长为程序生存期,因为存储区域不是栈区,所以不会因为退栈而被

char *p ="atbcdef";
*(p+) ='b';

销毁。


4、文字常量区
常量字符串就是放在这里的。程序结束后由系统释放。
常量,顾名思义,不可进行写操作,关于这一点的注意事项,请看下面这段错误代码;
char *p ="atbcdef";
*(p+) ='b';
程序运行时将报非法写入错误。
关于局部的字符串常量是存放在全局的常量区还是栈区,不同的编译器有不同的实现。可以通过汇编语言查看一下。VC环境下,局部常量就像局部变量一样存储于栈中,全局常量、字符常量存储于文字常量区。TC在常量区。

C++内存布局详解的更多相关文章

  1. 【转载】图说C++对象模型:对象内存布局详解

    原文: 图说C++对象模型:对象内存布局详解 正文 回到顶部 0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看.本文的结论都在 ...

  2. 图说C++对象模型:对象内存布局详解

    0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...

  3. c++ 对象内存布局详解

    今天看了的,感觉需要了解对象内存的问题.参考:http://blog.jobbole.com/101583/ 1.何为C++对象模型? 引用<深度探索C++对象模型>这本书中的话: 有两个 ...

  4. 好文章系列C/C++——图说C++对象模型:对象内存布局详解

    注:收藏好文章,得出自己的笔记,以查漏补缺!     ------>原文链接:http://blog.jobbole.com/101583/ 前言 本文可加深对C++对象的内存布局.虚表指针.虚 ...

  5. C/C++ 内存布局详解(经典)(很久前不知哪儿转载的)

    一个由C/C++编译的程序除了存放函数二进制代码的程序代码段(code段)外,数据占用的内存大致分为以下几个部分: 1.栈区(stack) 存放局部变量.函数参数.返回数据.返回地址等.系统自动分配释 ...

  6. C语言的代码内存布局详解

    一个程序本质上都是由 BSS 段.data段.text段三个组成的.这样的概念在当前的计算机程序设计中是很重要的一个基本概念,而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配, ...

  7. 【翻译】Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

    [翻译]Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解) . . .

  8. Android开发重点难点1:RelativeLayout(相对布局)详解

    前言 啦啦啦~博主又推出了一个新的系列啦~ 之前的Android开发系列主要以完成实验的过程为主,经常会综合许多知识来写,所以难免会有知识点的交杂,给人一种混乱的感觉. 所以博主推出“重点难点”系列, ...

  9. C语言内存对齐详解(2)

    接上一篇:C语言内存对齐详解(1) VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式.VC 中提供了#pr ...

随机推荐

  1. 【D3】D3词汇表

    按字母顺序 axis:数轴或坐标轴表示两个维度上数据尺度的直线 bar chart:条形图 (参见Excel)以矩形宽度反映数值大小的图表形式 bar:条形以宽度反映数值大小的矩形(rect) bin ...

  2. 【php】php 连接数据库

    $mysql_server_name=""; //数据库服务器名称 $mysql_username=""; // 连接数据库用户名 $mysql_passwor ...

  3. linux任务前后台执行

    Linux任务前后台的切换 Shell支持作用控制,有以下命令实现前后台切换: 1. command& 让进程在后台运行 2. jobs 查看后台运行的进程 3. fg %n 让后台运行的进程 ...

  4. YII2 添加全局自定义函数

    方法一: 这种方法就是直接在入口文件web/index.php里面写函数,示例代码如下: 全局函数 function pr($var){ //do something } (new yii\web\A ...

  5. Vmware Tools 下载及安装方法

    Vmware Tools 下载及安装方法 王尚2014.11.20 一.介绍 VMware Tools 是VMware 虚拟机中自带的一种增强工具,相当于 VirtualBox 中的增强功能(Sun ...

  6. python 分支语句 循环语句

    分支语句 #if-else if a > b: print('aaa') else: print('bbb') #if-elif-else if a > b: print('a>b' ...

  7. Python爬虫从入门到放弃(二十一)之 Scrapy分布式部署

    按照上一篇文章中我们将代码放到远程主机是通过拷贝或者git的方式,但是如果考虑到我们又多台远程主机的情况,这种方式就比较麻烦,那有没有好用的方法呢?这里其实可以通过scrapyd,下面是这个scrap ...

  8. 读书笔记(一)—— 浅析浏览器渲染过程和html中的文件加载

    在构建页面时,我们会在html中载入一个或多个css和js文件.或许大家都已经习惯了"最佳实践"中,css文件应该放在<head>标签中引入,而js文件则是放在< ...

  9. com.mysql.jdbc.exceptions.MySQLSyntaxErrorException错误

    com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the ...

  10. PL/SQL 编程(二)游标、存储过程、函数

    游标--数据的缓存区 游标:类似集合,可以让用户像操作数组一样操作查询出来的数据集,实质上,它提供了一种从集合性质的结果中提取单条记录的手段. 可以将游标形象的看成一个变动的光标,他实质上是一个指针, ...