Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8018113
  • 博文数量: 159
  • 博客积分: 10424
  • 博客等级: 少将
  • 技术积分: 14615
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-14 12:45
个人简介

啦啦啦~~~

文章分类
文章存档

2015年(5)

2014年(1)

2013年(5)

2012年(10)

2011年(116)

2010年(22)

分类: C/C++

2010-07-14 13:02:43

作者:  
博客:linuxfocus.blog.chinaunix.net

在我们写代码的过程中,有很多函数由于经常的被调用,加上我们主观的惯性思维,认为这些函数很简单,结果反而更容易出错。

下面是我认为两个容易出错的函数,特点都是频繁被使用,但是对其返回值,我相信并不是所有人都很清楚。

1. snprintf:

缓冲区溢出是大多数软件容易出的bug,也是容易被攻击的地方。所以,现在的软件中,都开始使用snprintf代替sprintf,用strncpy代替strcpy。

但是现在谁能说出snprintf的返回值都有什么?

int snprintf(char *str, size_t size, const char *format, ...);——这是snprintf的原型。
它的返回值有如下几种情况:
1,负值:这个自然是出错了,很简单略过不提。
2,str的size足够大,那么返回实际打印字节数(不包括结尾的'\0');
3,str的size不足,返回的是什么呢?返回的不是实际打印字节数,而是要打印的字节数,其等于size或者大于size。

关于这最后一种情况,我相信至少有一半的程序员不知道或者不清楚,那么就很容易出现bug了。

2. fwrite/fread:

文件的I/O函数,在我们第一门的编程语言中都会涉及,但是如果一不小心,还是会出错。

其原型是size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

那么它的返回值什么?

还是估计一下,我猜测大概有1/10的人,返回的是写入的字节数。而正确答案是返回的是成功写入元素的个数——这个个数对应于参数中的count。

上面两个函数都是我们平时经常接触到的,认为很简单的函数,但是一不小心还是会出错。其实不只是返回值,还有一些函数也会导致我们错误的使用。我再举两个简单的函数。

1. strncpy.

char buf[MAX_SIZE];

strncpy(buf, str, ?)

这第三个参数应该填什么?根据snprintf的使用习惯,我们很容易选择使用sizeof(buf),那么这个表达式就是strncpy(buf, str, sizeof(buf))。

如果这么使用的话,恭喜你,引入了一个bug。

当我们使用snprintf的时候,如果buffer不够大的话,API虽然会截断字符串,但是buffer的结尾仍然会填上'\0'。但是strncpy不会。

这样当buffer不够大时,虽然这句strncpy不会有问题,但是,当你使用buf中的字符串时,就会出现问题,因为每月字符串结束符'\0'。

2. malloc和realloc

请看下面的两行代码,是否会引起crash。

char *p1 = malloc(0);

*p1 = 'a';

答案是不会。当malloc的参数是0时,实际上是系统仍然会分配一个字节的空间给p1。所以并不会引起crash。

那么,我们再接着加上2行代码,大家看看有没有问题。

p2 = realloc(p1, 0);

*p2 = 'a';

答案是系统会crash。因为realloc是一个很讨人厌的函数——一个函数被赋予了2项功能。

realloc的原型如下:

void * realloc ( void * ptr, size_t size );

当size大于0的时候,realloc是先施放ptr的内存,然后再申请size大小的内存返回;

但是当size等于0的时候,realloc却等于free。它将ptr指向的内存释放,并返回null。

这样上面的代码就会引起程序的crash。

因此可见,在我们编程的过程中,有多少小问题容易被忽视,而大多数bug都是由这些小问题引起的。

阅读(6423) | 评论(5) | 转发(5) |
给主人留下些什么吧!~~

GFree_Wind2011-03-02 22:14:31

caoxudong818: 看了一天您的博客,很喜欢,翔实深入。敬佩,要向您多学习。
我也喜欢c语言,但感觉水平还太差,希望能多看到您的文章。
希望以后我也可以写出这样的文章,与您.....
互相学习吧。我在用户层的方面还有些经验,但是内核方面也是新手。最近刚刚开始看内核代码,互相学习吧。

caoxudong8182011-03-02 22:07:48

GFree_Wind: 感觉新版有点问题。经常验证码输入正确了,还显示错误。提交后,验证码已经刷出来了,但是评论还未出。.....
看了一天您的博客,很喜欢,翔实深入。敬佩,要向您多学习。
我也喜欢c语言,但感觉水平还太差,希望能多看到您的文章。
希望以后我也可以写出这样的文章,与您交流。

GFree_Wind2011-03-02 22:04:24

caoxudong818: 顶,好文
为毛刚才的评论不显示。.....
感觉新版有点问题。经常验证码输入正确了,还显示错误。提交后,验证码已经刷出来了,但是评论还未出。

caoxudong8182011-03-02 18:35:29

顶,好文
为毛刚才的评论不显示。