首页 > 代码库 > 字符串数组越界bug(2)

字符串数组越界bug(2)

概述

数组下标从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库,它会简化你紧张的心情

字符串数组越界bug(2)