Blog / 阅读

打破陈规偏见,C/C++资源释放

by admin on 2014-04-02 12:13:00 in ,



陈规偏见,多源于已有的认知(或经验,或学识)和对权威的膜拜。

谁负责释放资源?

如下

[cpp] view plaincopy
char * fun(const char* str)  
{  
    size_t  len = strlen(str);  
    char* p = (char*) malloc( len+1 );   
    return p;  
}  


看到这样的代码,大部分有过C++加持的人或膜拜教科书的人(我承认我以前也是这样的人),会大喊:内存泄漏。
的确,fun函数申请了一块内存,但是fun函数没有负责释放,这个行为与“谁申请,谁释放”的信条极为冲突。
然而,加上如下注释呢?
[cpp] view plaincopy
//fun函数的返回值指向了使用malloc的方式申请了内存,当不再使用这个值时,需要用free释放  
char * fun(const char* str)  
{  
    size_t  len = strlen(str);  
    char* p = (char*) malloc( len+1 );   
    return p;  
}  


这样,内存释放的责任便落到了fun函数调用者的身上,一切就通顺了。
不过,仍然会有一部分人说“编码任务繁重,谁有时间去看注释”。
那我们来看看一个C的库函数:
[cpp] view plaincopy
FILE *fopen( const char *filename,const char *mode );  
fopen函数负责释放打开的文件句柄了吗?我们再使用fopen时,不一样看fopen的说明文档,自己调用fclose来释放资源吗?
为什么有的人对上面的fun函数和fopen函数是截然两种不同的态度?
恐怕原因在于迷信权威,fun函数是我们自己写的,fopen函数是业界权威写的。


谁负责释放资源?我个人认为,要看上下文,看语境,看场景,看项目中的约定等等。
为了说明问题,看下面的代码
[cpp] view plaincopy
//dst需要有足够的空间来容纳src  
void copystrA(const char * src , char * dst )  
{  
 size_t len = strlen(src);  
 for(size_t i = 0; i < len ; i++ )  
 {  
  dst[i] = src[i];  
 }  
 dst[len] = 0;   
}  
  
//返回值指向一块使用malloc分配的内存  
char * copystrB( const char *src)  
{  
 size_t len = strlen(src);  
 char * dst = (char *)malloc(len+1);  
 for(size_t i = 0 ; i < len ; i++ )  
 {  
  dst[i] = src[i];  
 }  
 dst[len] = 0;  
 return dst;  
}  
  
int main()  
{  
 const char * src = "hello world";  
  
 ////代码块A,copystrA/////  
 size_t len = strlen(src);  
 char * dstA = (char *)malloc(len+1);  
 copystrA(src ,dstA );  
 free(dstA);  
 ///////////////////////  
  
 ////代码块B,copystrB/////  
 char * dstB;  
 copystrB(src ,dstB);  
 free(dstB);  
 /////////////////////////  
  
 return 0;  
}  


 看到区别了吗?代码块B的效率比代码块A更高,因为代码块A多了一次重复的strlen计算。
谁申请谁释放的原则大方向是没有错的,也是应该坚持的,但是具体到细节场景,那就另当别论了。


写评论

相关文章

上一篇:shell脚本编程之终端打印

下一篇:DES加密算法详解- -

评论

写评论

* 必填.

分享

栏目

赞助商


热门文章

Tag 云