精华推荐:C++编程新手错误语录

来源:PConline  作者:宋宝华
精华推荐:C++编程新手错误语录
摘要:1.引言还记得当年学数学、英语都有个窍门,那就是搞个错题集。经常复习一下这个错题集,就可以避免下次犯同样的错误。而几乎所有的程序员都是从犯错误开始的,我们也很有必要总结一下编程新手的常见错误,本文的目的在于此。文中所列出的都是笔者在项目开发……

(8)“我想用malloc”、“我用不好malloc”

来看看一个变态程序:

/* xx.c:xx模块实现文件 */
int *pInt;
/* xx模块的初始化函数 */
xx_intial()
{
pInt = ( int * ) malloc ( sizeof( int ) );
...
}
/* xx模块的其他函数(仅为举例)*/
xx_otherFunction()
{
*Int = 10;
...
}

这个程序定义了一个全局整型变量指针,在xx模块的初始化函数中对此指针动态申请内存,并将pInt指向该内存首地址,并在xx模块的其他函数中都使用pInt指针对其指向的整数进行读取和赋值。

这个程序让我痛不欲生了好多天,扼腕叹息!这是我母校计算机系一位硕士的作品!作者为了用上malloc,拼命地把本来应该用一个全局整型变量摆平的程序活活弄成一个全局整型指针并在初始化函数中“动态”申请内存,自作聪明而正好暴露自己的无知!我再也不要见到这样的程序。

那么malloc究竟应该怎么用?笔者给出如下规则:

规则1 不要为了用malloc而用malloc,malloc不是目的,而是手段;
  规则2 malloc的真正内涵体现在“动态”申请,如果程序的特性不需动态申请,请不要用malloc;

上面列举的变态程序完全不具备需要动态申请的特质,应该改为:

/* xx.c:xx模块实现文件 */
int example;
/* xx模块的初始化函数 */
xx_intial()
{
...
}
/* xx模块的其他函数(仅为举例) */
xx_otherFunction()
{
example = 10;
...
}

规则3 什么样的程序具备需要动态申请内存的特质呢?包含两种情况:

(1)不知道有多少要来,来了的又走了

不明白?这么说吧,譬如你正在处理一个报文队列,收到的报文你都存入该队列,处理完队列头的报文后你需要取出队列头的元素。

你不知道有多少报文来(因而你不知道应该用多大的报文数组),这些来的报文处理完后都要走(释放),这种情况适合用malloc和free。

(2)慢慢地长大

譬如你在资源受限的系统中编写一文本编辑器程序,你怎么做,你需要这样定义数组吗?

char str[10000];

不,你完全不应该这么做。即使你定义了一个10000字节大的字符串,用户如果输入10001个字符你的程序就完完了。

这个时候适合用malloc,因为你根本就不知道用户会输入多少字符,文本在慢慢长大,因而你也应慢慢地申请内存,用一个队列把字符串存放起来。

那么是不是应该这样定义数据结构并在用户每输入一个字符的情况下malloc一个CharQueue空间呢?

typedef struct tagCharQueue
{
char ch;
struct tagCharQueue *next;
}CharQueue;

不,这样做也不对!这将使每个字符占据“1+指针长度”的开销。

正确的做法是:

typedef struct tagCharQueue
{
char str[100];
struct tagCharQueue *next;
}CharQueue;

让字符以100为单位慢慢地走,当输入字符数达到100的整数倍时,申请一片CharQueue空间。

【相关文章】好搜一下
修练8年:C++面向对象程序设计之体会

修练8年:C++面向对象程序设计之体会

六年前,我刚热恋“面向对象”(Object-Oriented)时,一口气记住了近…