C++内存动态分配及管理
内存动态分配与管理是C++灵活性的一种体现,本贴探讨C++中内存的动态分配与管理。
一、简单的内存分配
在C++中,引入了一对新的操作符new/delete来动态分配和释放内存。虽然旧的malloc/free仍然有效,但强烈建议不再使用它们。因为new/delete做了一些“我们不知道”的事情。比如有一个类A,我们执行下面的操作:
C++中总是先分配内存,然后调用A的构造函数。那么对应的操作可能是下面的样子:
现在我们知道:malloc/free只是简单的执行内存分配,而new/delete在分配内存的同时,还在这片内存上执行了对象的构造或析构。
二、多维数组的动态分配
有时候我们需要动态分配一个多维数组——比如创建一幅游戏地图。那么我们可以通过动态创建来完成。多维数组的分配有多种方式,如下:
1> 直接分配:
我们用二维数组为例,这个比较容易,如下:
这样就创建了一个三行四列的二维数组,释放操作如下:
也可以像下面操作,比较直观:
这样也创建了一个三行四列的二维数组,释放操作和上面一样。三维、多维的操作和二维的类似。
2> 多次分配:
我们也可以通过多重分配来模拟:
这样也创建了一个三行四列的二维数组,释放操作如下:
可以看出,创建、释放操作比第一种方法麻烦了不少。其余的操作基本一样。所以我们最好用第一种方式来动态创建多维数组。
三、几种new方法:
1> plain new:
这种普通的new方法我们只能通过异常检测来判断内存分配是否成功,而不是通过检测new返回的指针是否为NULL。因为C++标准规定:“plain new在分配失败后抛出std::bad_alloc异常,而不是返回NULL。”示例如下:
像下面的检测操作是无用的:
2> nothrow new:
我们可以通过nothrow来分配一片内存,这样如果分配失败,则返回NULL而不是抛出std::bad_alloc异常:
我们可以知道,哑元nothrow是C++中全局的一个nothrow_t的const对象。
3> placement new:
如果我们频繁动态创建/释放对象,那么我们可能会用到placement new方法,这种方法通过指定一片已动态分配的内存,来在上面执行对象创建操作,而不会重新分配内存。如下:
placement new操作只是简单的在pInterger所指向的内存上执行对象的构造。需要注意的是:placement new分配的内存需要我们自己显式调用析构函数,如:pObj->~ClassName();。
这种方法很有用,比如在一个太空游戏中要动态创建/释放很多的敌机、飞船,那么我们会用到placement new,将分配后要释放的内存简单的放到我们管理的内存池中,然后在下次有对象创建时简单的执行placement new即可。比如我们的内存池为CMemoryPool:
如果我们要创建飞船,那么在需要创建时只需在内存池中查询,如果有可用的内存,则返回一片可用内存并在上面执行placement构造,否则只是创建一份即可。
在飞船被击毁时,只需将它解除,然后添加到内存池即可:
这样就避免了频繁的创建/释放操作使堆千疮百孔了。综上我们简单介绍了C++中动态分配内存的管理等问题。
--By:YaFengZhang
--Date:2010.12.11
--Blog:http://blog.csdn.net/ZhangYafengCPP