第2章 这不是Bug,而是语言特性

无论在任何时候,如果遇到malloc(strlen(str))几乎可以断定它是错误的,而malloc(strlen(str)+1)才是正确的,因为字符串处理库函数都包含一个额外空间,用于容纳字符串结尾的’\0’字符。

多做之过,就是语言中存在某些不应该存在的特性。这些特性包括容易出错的switch语句、相邻字符串常量的自动连接、缺省全局作用域
在C语言中,const关键字并不真正表示常量,如:

const int two = 2;

switch(i)
{
	case 1: printf("case 1\n");
	case two: printf("case 2\n");
**error** ^^^ integral constant expression expected
	case 3: printf("case 3\n");
	default : ;
}

当在switch case语句中 几乎所有的case都需要以break结尾。

ANSI C引入一个新特性是相邻的字符串常量将被自动合并成一个字符串的约定,这就省掉了过去在书写多行信息时必须在行末添加’'的做法。
但这种自动合并意味着字符串数组初始化时,如果不小心漏掉一个逗号,编译器不会发出错误信息,而是将两个字符串合并在一起。

定义C函数时,在缺省情况下函数的名字是全局可见的。这个函数对于链接到它所在的目标文件的任何东西都是可见的。如果想限制对这个函数的访问,就必须加static关键字,这样其成为本文件可见。
根据实际经验,这种缺省的全局可见性多次被证明是个错误。软件对象在大多数情况下应该缺省地采用有限可见性。当程序员需要让它全局可见时,应该采用显式的手段。

C语言中属于“误做之过”的特性,就是语言中有误导性质或是不适当的特性。包括运算符重载(基本无问题),运算符优先级错误(基本无问题)。

输入函数gets()在新版编译器中已被警告不要使用。

少做之过的特性就是语言应该提供但未能提供的特性,如标准参数处理以及把lint程序(在UNIX上的C语言,其把编译器中所有的语义检查措施都分离出来。错误检查由一个单独的程序完成,这个程序称为“lint”)错误地从编译器中分离出来。

不要在代码中使用/* */进行注释。

在C语言中,自动变量在堆栈中分配内存。当包含自动变量的函数或代码块退出时,它们所占用的内存便被回收,它们的内容肯定会被下一个所调用的函数覆盖。这一切取决于堆栈中先前的自动变量位于何处,活动函数声明了什么变量,写入了什么内容等。原先自动变量地址的内容可能被立即覆盖,也可能稍后才被覆盖
最好的解决方案就是要求调用者分配内存来保存函数的返回值。为了提高安全性,调用者应该同时指定缓存区的大小。如:

void func(char *result, int size)
{
	strncpy(result, "That'd be in the data segment, Bob", size);
}
buffer = malloc(size);
func(buffer, size);
...
free(buffer);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值