Chinaunix首页 | 论坛 | 博客
  • 博客访问: 931746
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-26 09:40:01

1。在对字符串赋值前,必先用memset进行全部赋零操作
有人说这么安全。不知道证据从哪儿来的?
有人说多这一句也不多。不知道多哪一句才算多?

2。对于不再使用的指针变量,赋零
有人说这么安全。不知道证据从哪儿来的?
有人说多这一句也不多。不知道多哪一句才算多?

--------- 以下是俺觉得内容太少,而拉过来凑字数的,不是闲得发慌的话,不需要看 ---------

这两个恶习估计唯一的作用就是隐藏Bug,令错误难于被发觉。(这句话转自 chinaunix 上的一位牛人,深表赞同 )

第1个恶习,有个好例子,在论坛上出现过
char str[16];
memset( str, 0, 16 );
str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
printf( "%s", str );
如果没有memset这一句,结果就是错误的,所以他认为数组赋值前先memset一下是个很好的风格。
(正确的做法是str[3] = '\0')

对于 位比较 不在此列,比如将 str[16] 送入加密函数 void foo( void* p, size_t n )
那么 "abc \0 1" 和 "abc \0 2" 就是不等同的,在论坛中也见到过两次,有人问“我用DES3加密一个字符串,每次输入都是abc,但结果却不一样”,呵呵。

第2个恶习,就是重复释放的问题
int* p = new int;
delete p;
p = 0;
delete p;
如果没有p = 0;这一句,结果就是错误的,所以他认为这也是个很好的风格。
(正确的做法是删除重复的delete p。我们的目的是去除错误,而不是让错误不产生危害

对于p = 0 某些人(只是某些人而已)会用来在Debug版本中做释放检查,算是一种debug的手段,但不应该出现在正式的代码中。
而其实,一般的编译器都会在debug版本中做类似的行为,但绝不是 p = 0 这种傻叉叉的做法,而是 *(int*)p = 特值。
例如
p = new char[100];
p1 = p;
delete[] p; *(int*)p = 0xFEEEFEEE;
如果 *(int*)p1 == 0xFEEEFEEE 说明 p1 指向的内存已经被释放
阅读(5193) | 评论(28) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-26 09:43:09

c+++
这算恶习?你不会连吃饭睡觉也算恶习吧.

网友评论2012-11-26 09:43:00

CornWu
我认同Diviner兄防御性编程的说法。
对于一个持续作业的服务器来说,我宁愿多消耗系统资源来做防御性检测,也不宁愿让服务器偶尔崩溃导致经常重启服务器。


第2个恶习,就是重复释放的问题
int* p = new int;
delete p;
p = NULL;
delete p;
这种写法,看似很繁琐,但是对连续运行的系统来说,它是让系统连续运行不报错的写法。如果没有p = NULL;这行代码,那程序执行两次delete肯定报错。

int* p = new int;
delete p;
。。。此处有N多行代码
delete p;

如果代码是这样写,当错误发生时,怎么去查找错误?

网友评论2012-11-26 09:42:50

周星星
第一种,如果你想通过参数(而不是返回值)来判断是否成功,用lpFilename[0]='\0'而不是memset。另外,我反对的是“必先用 memset”,而不是在任何情况下都不许用memset。

第二种,当代码有错误,你想修改其它正确的地方,让某个错误被遮盖。那么这个错误是否可能完全被遮盖,如果不能的话,与其修修补补不停的去掩盖,不如大大方方的把错误去掉;掩盖错误的手段会不会导致原本正确的代码反而运行错误?阿荣说过:做正确的事,而不是把错误的事做正确。
就拿重复释放来说事,一旦出现重复释放的错误,大抵是因为逻辑错误了。代码大部分情况下是拷贝的
delete p1;
delete p1;
调试一遍我就知道第二句写错了应该是 delete p2,而如果
delete p1; p1=0;
delete p1; p1=0;
则完完蛋了。这就是正文中“这两个恶习估计唯一的作用就是隐藏Bug,令错误难于被发觉”的注解。

网友评论2012-11-26 09:42:41

Diviner
第一种,就拿winapi来说吧。
getmodulefilename,我把这个传递过去,万一失败了,这里没有赋值。

第二种,你说的是理想情况下,大家写代码习惯都不错,事实上是混乱逻辑的代码很常看到。

网友评论2012-11-26 09:42:32

周星星
第一种情况你举个事例,我没看明白
第二种情况不在此列,我说的是“不再使用的”,而你的情况是逻辑复杂(准确的说应该是“混乱”)到都不能肯定是否是“不再使用的”。不能肯定“不再使用”,只能当会再被使用到来看待,但大部分情况下,程序员是知道某指针在之后自己会不会用到它的(否则每段代码逻辑都如此混乱,那还得了。指针释放问题毕竟还只是最微不足道的小问题),因此每逢delete p必置p=0仍算恶习。