是时候放弃strdup了!

去年分析iPhone/iPodTouch上的数据库文件iTunesDB的时候,曾经研究过Winamp下的一个关于这个数据库的开源插件ml_ipod.dll,关于这个数据库的格式就不在这里详述了。只是在移植其中的代码的时候,发现了内存泄漏问题,而后通过跟踪源代码才发现这和strdup的使用有关系,于是Google了一把,找到了一篇文章,文章中解释了为什么要放弃strdup。

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
最近在看别人编写的C语言源代码,很多人喜欢使用strdup来复制字符串,我觉得这个习惯不好,因为如果想使自己的程序移植性更好的话,就忘记有这个函数吧。我否定它的主要原因是:
1)用strdup函数的时候,往往我们会忘记内存的释放,可能的原因是对于C库函数的了解不够,毕竟是其他模块分配内存,自己模块释放它。
2)在不同的平台上,我们对于strdup内存分配的函数可能采用不同的方法,比如在某些C库中用malloc来分配,而在某些C++库中,用new来分配(因为C++库可能重写了相关的C库代码)。所以对使用者在释放它的时候产生了很大的疑惑,是用free还是用delete[]来释放所分配的内存呢?!如果我们主管臆断,用free来释放它,操作未知。可能工作正常,可能是部分内存泄漏,也可能是程序崩溃。自己程序的正确性依赖于编译器,很不爽吧!

我觉得,在模块中,除非万不得已自己分配的内存需要其他模块释放,否则应该自产自销,尽量避模块之间的这种耦合性,减少内存泄漏的因素。那么读者可能会问,如果字符串复制经常用到,类似于下面的一个代码
char *dest = malloc(strlen(src) + 1);
assert(dest != NULL);
strcpy(dest, src);
经常要被使用,写3行代码比较罗嗦,那么不妨使用宏来搞定它吧。这样做的好处是确定了内存是用malloc分配的,移植性好多了,难道不是吗?!此外,自己定义的宏,分配内存后要释放,总不会忘记吧。

上述仅仅是个人的观点,仅供参考!
posted @ 2009-09-05 21:52  芈希有  阅读(1108)  评论(0编辑  收藏  举报