1、const其实并不是真正的常量(P32)
2、早期的gets()中的Bug导致了Internet蠕虫(P42)
gets()函数并不检查缓冲区的空间,事实上它也无法检查缓冲区的空间。如果函数的调用者提供了一个指向堆栈的指针,并且gets()函数读入的字符数量超过缓冲区的空间,gets()函数将会愉快地将多出来的字符继续写入到堆栈中,这就覆盖了堆栈原先的内容。——这就是病毒利用它来写入额外空间,并引发蠕虫病毒的前提。
推荐的方式是将
gets(line)
替换为
if(fgets(line, sizeof(line), stdin) == NULL)
exit(1);
3、相邻字符串常量自动连接(P45)
这个其实已经应用很普遍了,但是我个人用的比较少,特此记录一下。
4、返回一个指针?(P48)
这个话题围绕一个程序的BUG来展开,这个程序返回了局部变量的值的指针,这么说当然你一眼就能看得出来问题所在,但是在很多时候,这个错误却总是在你的眼皮子底下溜走。
作者提供了五种方式,只能说可以用,但唯一推荐的只有一个,详见作者的分析(P48)(不是什么高深的理论,你自己也能分析地出来)。
a.返回一个字符串常量的指针。因为常量存在静态数据存储区,所以指针没问题。
b.使用全局声明的数组。提到全局两个字,就知道这个方法有很大的局限性。
c.使用静态数组。下一次调用将覆盖这个数组内容。
char * func() {
static char buffer[20];
…
return buffer;
}
d.显式分配一些内存,保存返回的值。
char * func() {
char * s = malloc(120);
…
return s;
}
既然用到了malloc,就必然伴随着free,因此带来了内存管理的问题,增加了开发者负担。
e.(推荐)在调用前后,由函数调用者分配内存,并由其释放,在同一地方释放对于内存管理来说代价相对最小。
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);