四时宝库

程序员的知识宝库

C++|数组的不安全性及一个安全数组类的实现

在C++中,STL的map与set的元素通过键(key)来访问元素的值,而数组作为一种顺序结构,通过其元素的位置来访问其元素的值。

在C++中,数组名相当于一个指针常量,下标内的数字相当于是指针的偏移位置,如arr[i],相当于*(arr+i)。

在C++中,如果定义的数组:int arr[n],其指针arr偏移的范围应该是n>=0&&n<10,但偏移器并不检查n的取值范围,这就是数组的不安全的原因,如下例:

#include <iostream>
using namespace std;
const int SIZE = 10;
int main()
{
	int before = 111;
	int arr[SIZE];
	for(int i=0; i<10; ++i)
		arr[i]=i;
	int after = 999;
	cout << "arr[-2] 的值为 : " << ++arr[-2] <<endl;
	cout << "arr[2] 的值为 : " << arr[2] <<endl;
	cout << "arr[9] 的值为 : " << arr[9]<<endl;
	cout << "arr[10] 的值为 : " << ++arr[10]<<endl;
	cout<<before<<" "<<after<<endl;
	system("pause");
	return 0;
}
/*
arr[-2] 的值为 : 1000
arr[2] 的值为 : 2
arr[9] 的值为 : 9
arr[10] 的值为 : 112
112 1000
*/

从上面实例的代码运行后可见,编译器并没有检查数组下标的边界,当用指针arr偏移出其边界时,修改的是临近区域的值。

C风格的字符串也因为同样的原因,存在不安全的因素,为此,在C++中也定义了string类,对C风格的字符串进行封装,同样的,STL也封装了动态数组,建立了vector类。关于vector类的实现代码,可见:

C\C++语言25|综合理解类:vector类的自定义

下面的实例就是封装一个数组类,对下标的边界进行检查:

#include <iostream>
using namespace std;
const int SIZE = 10;
class Arrs
{
private:
	int arr[SIZE];
public:
	Arrs()
	{
		register int i;
		for(i = 0; i < SIZE; i++)
		{
			arr[i] = i;
		}
	}
	int& operator[](int i)
	{
		if( i >= SIZE )
		{
			cout << "索引超过最大值" <<endl;
			// 返回第一个元素
			return arr[0];
		}
		if( i < 0 )
		{
			cout << "索引小于0" <<endl;
			// 返回第一个元素
			return arr[0];
		}
		return arr[i];
	}
};
int main()
{
	int before = 111;
	Arrs arr;
	int after = 999;
	cout << "arr[-1] 的值为 : " << arr[-1] <<endl;
	cout << "arr[2] 的值为 : " << arr[2] <<endl;
	cout << "arr[9] 的值为 : " << arr[9]<<endl;
	cout << "arr[10] 的值为 : " << arr[10]<<endl;
	cout<<before<<" "<<after<<endl;
	system("pause");
	return 0;
}
/*
索引小于0
arr[-1] 的值为 : 0
arr[2] 的值为 : 2
arr[9] 的值为 : 9
索引超过最大值
arr[10] 的值为 : 0
111 999
*/

从上面实例的代码运行后可见,当偏移出其类的成员数组的边界时,因做了边界检查,并不会修改临近变量的值,一定程度上实现了安全性。

-End-

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接