从C到C++再到Obj-C内存管理学习笔记(二)

上一篇讲完内存管理香港概念之后,这一篇重点介绍内存堆栈、malloc()-free()a、new-delete的使用及实现过程。

首先,我们必须知道的是,每个程序在内存中分为几个存储区,静态存储区,堆栈,堆,自由存储区、常量存储区及程序二进制代码的存储区。还有就是CPU的寄存器。如下图所示:

静态存储区:存放上一篇中提到的静态变量,包括静态全局变量、静态内部变量、静态局部变量,这些变量在程序编译时被存放到静态存储区。

常量存储区:主要存放程序中涉及到的常量,比如字符串常量就是存放在这个区。

寄存器:寄存器可以放到这里面也可以不包括,因为他是属于CPU的,为了全面,我还是把他包括进来了。

程序二进制代码区:主要存放的是程序代码被编译器转化而成的二进制代码。

栈区:堆栈区存放的是自动变量在嵌套的代码块结构中,每定义一个变量就往栈里添加变量,其大小一般为1M。代码块结束时局部变量弹出。值得注意的是,这里的弹出并非变量真的从栈中弹出,而是栈顶指针向下移动,原先的变量不销毁,等到有新的自动变量进栈时,进行覆盖,指针向上移动。如下图所示:

需要注意的是,当我们调用递归函数时,如果递归层次太深,超过栈的内存上限时,便出现栈溢出。

堆区:堆区一般是用来存放我们动态分配的变量,如用malloc()及new分配到的内存。如malloc向堆区发起指定大小的内存申请,如果堆区有足够的内存空间便返回相应的地址空间,不成功时操作将等待有内存归还。如下图所示:

值得注意的是,堆区的内存分配是通过一张空闲链表来实现的,申请的时候,如果空闲链表的大小比所申请的空间大,则返回相应的内存区间,否则申请不成功。

当代码中通过free()、delete释放内存时,相应的内存返回给空闲链表,空闲链表再将其组织起来,等待下一次的申请。

堆区内存分配的特点是分配快回收慢,适合大内存的对象。

相比起栈区,堆区主要靠手动管理,而栈区自动管理;堆区最大可以到4G,而栈区只有1M;堆区在内存管理上存在大量内存碎片,栈区几乎没有碎片;堆区需要组织内存空间,效率比起栈区也低。

下面再介绍下关于malloc(),calloc(),realloc()的区别:

malloc()只有一个参数,就是所需要的内存空间,申请完不初始化;

calloc()有两个参数,一个是内存空间的个数,另一个是每个内存空间的大小,申请完每位会自动初始化为0;

realloc()是对内存大小重新分配,如果新申请的内存比原来的大则返回原来的地址,新增加的地址不初始化,如果是减少则会返回新的内存地址。

值得注意的是,在使用malloc()时,要记得使用free()适时释放废弃的变量空间,否则会内存泄露。除非在接近程序结束时可以不free(),程序结束后所有内存自动清空。

下面介绍有关new操作。new是C++的关键字,在C语言中没有。

在C++中对类对象使用new时,会执行三个步骤:

1.在堆中申请内存空间;

2.执行构造函数;

3.返回对象。

需要动态分配内存时使用new或new [],不需要的时候使用delete或delete[]释放内存,这样做防止内存泄露。

除了常规的new之外,还可以通过布局new来手动分配内存及内存位置。如:

<span style="font-size:18px;">char buffer[512];

double *p;

p = new (位移量+N*sizeof(double)) double[N];</span>

代码中创建了一个缓冲区,使用布局new在缓冲区上的指定位置(位移量的位置)分配内存空间,与常规new操作不同,布局new操作不知道哪些内存被使用,所以这就需要程序猿自己管理内存位置。

还有一点需要注意的是使用布局new时,如果缓冲区不是动态分配的,那么不能用delete p[]之类的操作释放内存,所申请的内存会随着缓冲区(自动变量)的释放而释放。只有当缓冲区也是动态分配时才可以用delete释放内存空间。

时间: 2024-10-28 23:23:32

从C到C++再到Obj-C内存管理学习笔记(二)的相关文章

从C到C++再到Obj-C内存管理学习笔记(三)

前两篇介绍了C与C++的内存管理,这一篇介绍一下Object-C的内存管理. Object-C是C的超集,所有C语言的特性在Object-C都可以实现. 然而在内存管理上还是存在一些不同的地方. Object-C即面向对象C语言,其大部分的类型基于Cocoa框架,常见的有NS开头类型. 所以Object-C中大部分类型也都是以类为基础的. Object-C中类存放于堆而非栈,故一般类对象定义都以指针形式,如: <span style="font-size:18px;">NS

C++ Primer 学习笔记_73_面向对象编程 --再谈文本查询示例

面向对象编程 --再谈文本查询示例 引言: 扩展第10.6节的文本查询应用程序,使我们的系统可以支持更复杂的查询. 为了说明问题,将用下面的简单小说来运行查询: Alice Emma has long flowing red hair. Her Daddy says when the wind blows through her hair, it looks almost alive, like a fiery bird in flight. A beautiful fiery bird, he

C++ Primer 学习笔记_74_面向对象编程 --再谈文本查询示例[续/习题]

面向对象编程 --再谈文本查询示例[续/习题] //P522 习题15.41 //1 in TextQuery.h #ifndef TEXTQUERY_H_INCLUDED #define TEXTQUERY_H_INCLUDED #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <set> #include <map&g

Android学习笔记(十八)——再谈升级数据库

//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 之前我们为了保证数据库中的表是最新的,只是简单地在 onUpgrade()方法中删除掉了当前所有的表,然后强制重新执行了一遍 onCreate()方法.这种方式在产品的开发阶段确实可以用,但是当产品真正上线了之后就绝对不行了.想象以下场景,比如你编写的某个应用已经成功上线,并且还拥有了不错的下载量.现在由于添加新功能的原因,使得数据库也需要一起升级,然后用户更新了这个版本之后发现以前程序中存储的本地数据全部丢失了.

Android学习笔记(四)——再探Intent

//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 我们可以使用 Intent 来启动一个活动, 还可以在启动活动的时候传递数据的,下面一起来看一下: 一.向下一个活动传递数据 Intent中提供了一系列 putExtra()方法的重载,可以把我们想要传递的数据暂存在 Intent 中,启动了另一个活动后,只需要把这些数据再从Intent 中取出就可以了.例如我们可以在mainactivity中创建一个字符串,然后把它传递到second_activity里: 1)先在

js的call(obj,arg)学习笔记

var add=function (a,b){ return(a+b); } var sub=function (a,b,c){ return(a-b-c); } sub.call(add,1,2,3) //示例的意思时指用sub对象来替换add对象,并传入参数 //使用call来实现继承 function class1(){ this.name="lee"; this.say=function(){ console.log(this.name); } } function class

Android学习笔记(三四):再谈Intent(上)-一些知识

在Android学习笔记(七):多个Activity和Intent中,我们先在学会了如何使用intent在代码中唤起activity.此处作深一步地学习. 什么是Intent intent是对一个操作处理的抽象描述.context可以在使用startActivity(intent)来launch一个actvivity,就如我们在学习笔记(七)中的处理,也是最常用的方式,将activity在我们的应用中整合:可以在通过sentBroast(intent)来广播给任何有兴趣的BroadcastRec

Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批

最近有个特殊的需求,客户想做二次审批,就是审批通过后,再走一次审批流程.最开始一想,这还不简单,审批通过后,直接把状态改成draft就完了,后来一试,发现一堆问题,比如第一次审批完后,界面是不允许修改的,直接改成draft就又可以修改了:再比如审批活动记录的查找以及死循环的问题等等.于是自己动手单独写了一个公用的再审批插件,下面介绍详细的实现步骤:   一.添加字段以控制再审批的次数 添加一个字段 new_approval_count, 再审批一次就把它加1.如果只要再审批一次,那么大于1就退出

OpenCV学习笔记(四十)——再谈OpenCV数据结构Mat详解

原文:http://blog.csdn.net/yang_xian521/article/details/7107786 我记得开始接触OpenCV就是因为一个算法里面需要2维动态数组,那时候看core这部分也算是走马观花吧,随着使用的增多,对Mat这个结构越来越喜爱,也觉得有必要温故而知新,于是这次再看看Mat. Mat最大的优势跟STL很相似,都是对内存进行动态的管理,不需要之前用户手动的管理内存,对于一些大型的开发,有时候投入的lpImage内存管理的时间甚至比关注算法实现的时间还要多,这