概述
数组下标从0開始,尽管从初学都已经知道,《陷阱与缺陷》重复强调,而在指尖运动中,就有那么几次不小心,让“精子”掉进这个“洞里”!其次,C语言字符串必须以0收尾!
bug:
1-动态malloc或静态分配size大小字符串,存储size个字符,导致无0收尾,逾越警戒线,站在悬崖边了!
2-动态malloc或静态分配size大小字符串,訪问或设置 [ size ] 字符
3-动态malloc或静态分配size大小字符串,没有初始化,导致无0收尾,读取整串越界(VC下常见烫烫。。。,以前一个刚開始学习的人说他看到吓坏了,以为机器要暴喽)幸运的话,能在越界内存中遇到个0结束输出,不幸运喽,段错误,把你当成攻击者,暴力中止!
bug演示样例:
string = search_get_string_hash_table(word); if(string == NULL) { //哈希表中不存在此串 string = malloc_str(size);//分配内存,然后拷贝 if(string == NULL) return ERR_MEM; strncpy(string, word, size); string[size + 1] = 0; //bug,->string[size] = 0;注意在malloc_str中分配的是size+1字节,所以最后一个是string[size] put_string_hash_table(string);//放入哈希表 } //哈希表中存在此串 return string;
这是个人写的代码,还记得写完strncpy后,立刻在后面来了这句string [ size + 1 ] = 0;收尾的语句。拷贝了size字节,size+1字节收尾,想都不带多想一点的,认为非常自然^_^,敲的还挺潇洒。擦,等到哈系表出现一堆不须要的字符串后,不潇洒了。尽管非常低级,可是总会发生。尽管平时不会犯,熬夜加班后就是可能发生。这就是细节决定成败,四两拨千斤的活生生样例。
解决的方法:
1-动态分配用调用memset(addr, 0, size),静态 = { 0 }初始化,养成习惯
2-訪问边界字符时候,比較下标和大小是不是差1
3-假设须要逐个訪问,那么逆序递减訪问数组,下标以0结束是个不错选择,可是字符串一般不可行!字符串没有倒序输出的。
4-最笨的方法:牢记数组下标范围[0 - size-1],使用时候多瞅两眼!
5-自己封装须要的接口
6-使用C++string库,它会简化你紧张的心情