捕捉数组越界访问问题

有时候,在数组上实现一个算法的时候,往往需要在算法中把数组分解成一些子数组。如果在这些子数组上出现越界访问,代表算法的实现有问题。但这些问题常常不容易发现。

这时候,可以用带有数组越界访问检测功能的重载数组来暂时替代这些子数组,来捕捉算法的实现的越界访问问题。

class array {
public:
        int *save;
        int save_len;

        int *a;
        int len;
        array(int *a, int len):a(a),len(len){
                save=a, save_len=len;
        }
        void moveto(int p) {
                if( &a[p]>save+save_len) {
                        printf("overflow at %d\n", &a[p]-save);
                }
                if (&a[p]<save) {
                        printf("underflow at %d\n", &a[p]-save);
                }
                a=&a[p];
        }
        void setlen(int l) {len=l;}
        int &operator[](int i) {
                int *p;

                if(i<0 || i>=len) printf("relative overflow at %d, relative a= &
s[%d], a.len=%d\n", 
                        i, a-save, len);
                p= &a[i];
                if(p<save) printf("underflow at %d, relative %d\n", p-save, p-a);
                if(p>save+save_len) printf("overflow at %d, relative %d\n", p-save, p-a);

                return *p;
        }
        void operator=(int *p) { moveto(p-a); }
};

比如下面这个fib查找法的实现就有问题:

int search4(int key, int *a, int n)
{
        int *save=a;
        int fib, prev;
        int tmp;
        prev=0, fib=1;
        while(fib<n-1) {
                tmp = fib;
                fib+=prev;
                prev = tmp;
        }

        while(n>0) {
                while(n-1<fib){
                        tmp=prev;
                        prev = fib -prev;
                        fib=tmp;
                }

                tmp = fib-1;
                if (key <a[tmp]) n=fib;
                else if (key>a[tmp]) a=&a[tmp+1];
                else return &a[tmp]-save;
        }
        return -1;
}

替代之后变为:

int search4(int key, int *ar, int n)
{
        int *save=ar;
        int fib, prev;
        int tmp;
        array a(ar,n);

        prev=0, fib=1;
        while(fib<n-1) {
                tmp = fib;
                fib+=prev;
                prev = tmp;
        }

        while(n>0) {
                while(n-1<fib){
                        tmp=prev;
                        prev = fib -prev;
                        fib=tmp;
                }

                tmp = fib-1;
                if (key <a[tmp]) {n=fib;a.setlen(n);}
                else if (key>a[tmp]) {a=&a[tmp+1];a.setlen(a.len-tmp-1);}
                else return &a[tmp]-save;
        }
        return -1;
}

加上测试所需的main()函数:

int main()
{
        int a[21];

        int i;
        int n;
        n=sizeof(a)/sizeof(int);
        for(i=0; i<n;i++) a[i]=i;

        int u;
        for(u=0; u<10; u++) {
        i = search4(u, a, n);
        printf("i=%d\n", i);
        }
        return 0;        
}

编译之后,就可以把隐藏的越界访问查出来了。

i=0
i=1
i=2
relative overflow at 2, relative a= &s[3], a.len=2
i=3
i=4
relative overflow at 4, relative a= &s[5], a.len=3
i=5
relative overflow at 4, relative a= &s[5], a.len=3
i=6
i=7
relative overflow at 7, relative a= &s[8], a.len=5
i=8
relative overflow at 7, relative a= &s[8], a.len=5
i=9
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值