相信很多小伙伴在进行C语言学习和开发过程中都会遇到一个常见的bug,那就是数组越界,对于数组越界其主要是可能影响到正常的程序逻辑,其非常容易伪装成其他问题进而表现出来,比如由于越界篡改了相关数据,其暴露的现场就是相应数据被改后的现象,这样几乎无法直接从现象找到越界的位置。
那么对于大部分优秀的C语言开发者而言,更多的是养成了良好的编程习惯,对于数组越界的访问变量进行防御性限制,从而防止越界访问的问题。当然对于要求编写高效的代码,就需要工程师们对代码进行严格的把控,以降低越界风险。
然而C++作为一种带面向对象属性的编程语言,也认为是C语言的升级版本,那是否存在一种不错的方式来解决该问题,让开发者们把更多的注意力花在设计和代码逻辑上来呢?
当然是有的,大部分情况下,都会采用数组类代替原生的数组类来进行开发与编写,那么下面就简单演示一下数组类是如何最大程度上限制开发人员数组越界的。
参考代码如下:
#include<iostream>
using namespace std;
template <class type>
class cArray
{
public:
cArray(int size); //构造函数
~cArray(); //析构函数
type & operator[](int i);//重载[]运算符
private:
int length;
type *a;
};
//构造函数定义
template <class type>
cArray<type>::cArray(int size)
{
a = new type[size]; //动态申请内存
if(!a)
{
cout<<"动态空间申请失败!"<<endl;
exit(1);
}
//获得申请的内存长度
length = size;
//重新初始化各个成员
for(int i = 0;i < size ;i++)
{
a[i] = 0;
}
}
//[]操作符重载
template <class type>
type & cArray<type>::operator[](int i)
{
if(i < 0 || i > length - 1)//防止越界
{
cout<<"array["<<i<<"]越界并退出程序!\n";
exit(2);
}
return a[i];
}
//析构函数处理
template <class type>
cArray<type>::~cArray()
{
delete [] a; //释放构造函数申请的资源
}
//主测试函数
int main(void)
{
cArray<int> array1(10);
cArray<double> array2(5);
for(int i = 0;i < 10;i++)
{
array1[i] = i;
}
for(int i = 0;i < 5;i++)
{
array2[i] = i+0.1;
}
array1[20] = 10; //数组越界测试
return 0;
}
如上程序通过类模板构造了一个数组模板类,通过构造函数自动分配内存、析构函数释放不用内存、重载运算符[]。在main函数中应用该类与原生数组的使用几乎一个样。
当然效率上相比原生数组大有损伤,目前对于大部分应用是可以接受的,比如可以通过相应的调用接口来监控数组的使用情况,比如当访问array有越界行为的时候,通过[]重构监控和判断,并进行合理的拦截,这样也就在一定程度山规避掉了数组越界的风险。
转载自:原文