Cocos2d-x 的内存管理(4)
正是因为这两个原因, 你几乎不能在任何成熟的代码中看到这样的设计. 但是, 总有人经受不了使用看起来简单的这个诱惑, 比如cocos2d-x中CCFileUtils类的两个接口:
/**
@brief Get resource file data
@param[in] pszFileName The resource file name which contains the path.
@param[in] pszMode The read mode of the file.
@param[out] pSize If the file read operation succeeds, it will be the data size, otherwise 0.
@return Upon success, a pointer to the data is returned, otherwise NULL.
@warning Recall: you are responsible for calling delete[] on any Non-NULL pointer returned.
*/
unsigned char* getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize);
/**
@brief Get resource file data from a zip file.
@param[in] pszFileName The resource file name which contains the relative path of the zip file.
@param[out] pSize If the file read operation succeeds, it will be the data size, otherwise 0.
@return Upon success, a pointer to the data is returned, otherwise NULL.
@warning Recall: you are responsible for calling delete[] on any Non-NULL pointer returned.
*/
unsigned char* getFileDataFromZip(const char* pszZipFilePath, const char* pszFileName, unsigned long * pSize);
这种直接返回数据的接口自然比fread这样的接口看起来容易使用很多, 同时还通过一个warning的注释表明了, 应该使用delete[]来释放返回的缓存, 以避免前面提到的第一个问题, 但是, 不管再怎么做, 当你将cocos2d-x编译成动态库, 然后尝试使用上述两个API, 等待你的就是错误. 有兴趣的可以尝试.
这种API还是偶尔能见到, 有的时候可能还不如上面这个例子这么明显, 比如当一个函数要求传入Class** obj参数, 并且返回对象的时候, 其实也已经是一样的效果了.
再次声明, 个人认为这种API本身就是错误, 不推荐在任何时候使用, 看到这么设计的API, 也最好不要在任何时候调用.
C++对内存管理的改进
上述提到的几种涉及内存分配的API设计虽然是C语言时代的, 但是基本也适用于C++. 只是在C++中, 在Class层面, 对内存管理进行了一些新的改进.
有new就delete, 有malloc就free, 听起来很简单, 但是在一些复杂情况下, 还是会成为负担, 让代码变得很难看. 更不要提, 程序员其实也是会犯错误的. C++对此的解决之道之一就是通过构造函数和析构函数.
看下面的例子:
在极其简单的情况下, 我们这样就能保证内存不泄漏:
const int32_t kBufferSize = 32;
void Test1() {
char *buffer = new char[kBufferSize];
// code here
delete[] buffer;
}
但是, 这仅限于最简单的情况, 当有可能的错误发生时, 情况就复杂了:
const int32_t kBufferSize = 32;
bool Init() {
char *buffer = new char[kBufferSize];
bool result = true;
// code here
if (!result) {
delete[] buffer;
return false;
}
char *buffer2 = new buffer[kBufferSize];
// code here
if (!result) {
delete[] buffer;
delete[] buffer2;
return false;
}
相关新闻>>
- 发表评论
-
- 最新评论 更多>>