Cocos2d-x 的内存管理(5)
delete[] buffer;
delete[] buffer2;
return true;
}
仅仅是两次错误处理, 分配两段内存, 你不小心的写代码, 就很有可能出现错误了. 这不是什么好事情, 更进一步的说, 其实, 我上面这段话还是基于不考虑异常的情况, 当考虑异常发生时, 上述代码就已经是可能发生内存泄漏的代码了. 考虑到异常, 当尝试分配buffer2的内存时, 假如分配失败, 此时会抛出异常(对, 在C++中普通的new分配失败是抛出异常, 而不是返回NULL), 那么实际上此时buffer指向的内存就没有代码负责释放了. 在C++中, 讲buffer放入对象中, 通过析构函数来保证内存的时候, 就不会有这样的问题, 因为C++的设计保证了, 无论以何种方式退出作用域(不管是正常退出还是异常), 临时对象的析构函数都会被调用.
代码大概就会如下面这样:
const int32_t kBufferSize = 32;
class Test {
public:
Test() {
buffer_ = new char[kBufferSize];
}
~Test() {
delete[] buffer_;
}
bool process() {
// code here
return true;
}
private:
char *buffer_;
};
bool Init2() {
Test test;
bool result = test.process();
if (!result) {
return false;
}
Test test2;
result = test2.process();
if (!result) {
return false;
}
return true;
}
在最简单的情况下, 我们也没有必要构造一个类似上面这种纯粹为了存储Buffer的类, C++ 11中提供了智能指针来完成上述工作:
#include <stdio.h>
#include <stdint.h>
#include <memory>
using namespace std;
const int32_t kBufferSize = 32;
bool Init2() {
unique_ptr<char[]> buffer{new char[kBufferSize]};
bool result = true;
// code here
if (!result) {
return false;
}
unique_ptr<char[]> buffer2{new char[kBufferSize]};
// code here
if (!result) {
return false;
}
return true;
}
C++ 11还提供了支持引用计数的智能指针shared_ptr, 但是鉴于智能指针病毒般的传播特性, 建议仅在自己可控制的局部使用, 不在API中出现.
基本上, C++的内存管理虽然是纯手动管理+智能指针结合的较为原始方式, 但是思路还是比较清晰的, 即使牵涉到容器等更加复杂的情况, 其实还是遵循最基本的原则. 当然, 不要跟自动垃圾回收去比使用的方便.
在C++ 11放弃了可选的垃圾回收后, 短期就不要期望C++有垃圾回收机制了, C++这么强烈的期望手动管理内存, 很大程度上是效率的考虑, 即使是现在我看到一些文章说, 好的垃圾回收器效率已经超过一般的手动内存管理了. 然而, 我没有看到任何文章敢说, 好的垃圾回收器, 效率上可以超过好的手动内存管理……
Objective-C的内存管理
Objective-C(以下简称objc)其实已经有可选的垃圾回收功能了, 只不过在iOS上暂时还无法使用(应该是效率上的考虑), 不知道哪天iOS的SDK版本可以使用垃圾回收, 开发app就更简单了.
objc的内存管理自成一派, 将引用技术和内存池直接加入了语言特性.(这么说其实有待商榷, 因为引用计数等是NextStep库的特性, 但是鉴于使用objc就几乎肯定使用NextStep库, 所以这么说也可以接受)
相关新闻>>
- 发表评论
-
- 最新评论 更多>>