服务器之家

服务器之家 > 正文

C++索引越界的解决方法

时间:2021-12-10 15:04     来源/作者:Welcom to LyAsano’s blog!

避免"索引越界"错误的规则如下(针对C++):

  • 不要使用静态或动态分配的数组,改用array或vector模板
  • 不要使用带方括号的new和delete操作符,让vector模板为多个元素分配内存
  • 使用scpp::vector代替std::vector,使用scpp::array代替静态数组,并打开安全检查(自动在使用下标访问提供了索引边界检查)

C++中创建类型T的对象的数组方式如下:

?
1
2
3
4
5
6
7
#define N 10
T static_arr[N]; //数组长度在编译时已知
 
int n=20;
T* dynamic_arr=new T[n]; //数组长度在运行时计算
 
std::vector<T> vector_arr; //数组长度在运行时进行修改

1. 动态数组

  采用的办法是继承std::vector<T>,并重载<< 、[]运算符,提供一个能够捕捉越界访问错误的实现。

  实现代码和测试如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//scpp_vector.h
#ifndef  _SCPP_VECTOR_
#define  _SCPP_VECTOR_
 
#include <vector>
#include "scpp_assert.h"
 
namespace scpp {
 
    //wrapper around std::vector,在[]提供了临时的安全检查:重载[] <<运算符
    template<typename T>
    class vector : public std::vector<T> {
        public:
             typedef unsigned size_type;
 
             //常用的构造函数 commonly use cons
             explicit vector(size_type n=0) : std::vector<T>(n) {
 
             }
             vector(size_type n,const T& value) : std::vector<T>(n,value) {
 
             }
 
             template <class InputIterator> vector(InputIterator first,InputIterator last)
                 : std::vector<T>(first,last) {
 
             }
             
             //Note : we don't provide a copy-cons and assignment operator  ?
 
            //使用scpp::vector提供更安全的下标访问实现,它可以捕捉越界访问错误
             T& operator[] (size_type index) {
                 SCPP_ASSERT( index < std::vector<T>::size() ,
                     "Index " << index << " must be less than " << std::vector<T>::size());
                 return std::vector<T>::operator[](index);
             }
 
             //? difference
             const T& operator[] (size_type index) const {
                 SCPP_ASSERT( index < std::vector<T>::size() ,
                     "Index " << index << " must be less than " << std::vector<T>::size());
                 return std::vector<T>::operator[](index);
             }
 
             //允许此函数访问这个类的私有数据
             //friend std::ostream& operator<< (std::ostream& os,const ) ?
            };
} //namespace
 
template<typename T>
inline  std::ostream& operator<< (std::ostream& os,const scpp::vector<T>& v) {
    for(unsigned i=0 ;i<v.size();i++) {
            os << v[i];
            if( i+1 < v.size()) os << " ";
    }
    return os;
}
 
 
#endif
 
//test_vector.cpp
#include "scpp_vector.h"
#include <iostream>
 
using namespace std;
int main() {
    //usage-创建一个具有指定数量的vector:scpp::vector<int> v(n); 把n个vector元素都初始化为一个值:scpp::vector<int> v(n,val)
    //方法3:scpp::vector<int> v; v.reserve(n),表示开始的vector是空的,对应的size()为0,
    //并且开始添加元素时,在长度达到n之前,不会出现导致速度降低的容量增长现象
    scpp::vector<int> vec;
    for(int i=0;i< 3;i++){
        vec.push_back(4*i);
    }
    cout << "The vector is : "<< vec <<endl;
 
    for(int i=0;i <= vec.size();i++) {
        cout << "Value of vector at index " << i << " is " << vec[i] << endl;
    }
    return 0;
}

  我们直接使用scpp::vector而尽量不与std::vector交叉使用。

2.静态数组

  静态数组是在栈上分配内存,而vector模板是在构造函数中用new操作符分配内存的,速度相对慢些,为保证运行时效率,建议使用array模板(同样也是栈内存),实现代码和测试如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//scpp_array.h
#ifndef _SCPP_ARRAY_H_ 
#define _SCPP_ARRAY_H_
 
#include "scpp_assert.h"
 
namespace scpp {
 
//wrapper around std::vector,在[]提供了临时的安全检查
//fixed-size array
template<typename T,unsigned int N>
class array {
    public:
         typedef unsigned int size_type;
 
         //常用的构造函数 commonly use cons
        array() {}
        explicit array(const T& val) {
            for(unsigned int i=0;i < N;i++) {
                     m_data[i]=val;
                 }
        }
                 
        size_type size() const {
            return N;
        } //must use const if we use the size()
             
        //Note : we don't provide a copy-cons and assignment operator  ?
 
        T& operator[] (size_type index) {
             SCPP_ASSERT( index < N,
                     "Index " << index << " must be less than " << N);
             return m_data[index];
         }
 
         //? difference
        const T& operator[] (size_type index) const {
             SCPP_ASSERT( index < N ,
                     "Index " << index << " must be less than " << N);
             return m_data[index];
        }
 
         //模拟迭代器的begin和end方法
         //访问方法accessors
        T* begin() {
            return &m_data[0];
        }
 
        const T* begin() const {
            return &m_data[0];
        }
 
         //返回越过数组尾部的迭代器
        T* end() {
             return &m_data[N];
        }
 
        const T* end() const {
             return &m_data[N];
        }
    private:
        T m_data[N];
    };
} //namespace scpp
 
template<typename T,unsigned int N>
inline  std::ostream& operator<< (std::ostream& os,const scpp::array<T,N>& v) {
    for(unsigned int i=0 ;i< N;i++) {
            os << v[i];
            if( i+1 < v.size()) os << " ";
    }
    return os;
}
#endif
 
//test_array.cpp
#include "scpp_array.h"
#include <iostream>
#include <algorithm> //sort algorithm
using namespace std;
int main() {
    //use vector/array class instead of static array or dynamic array
    scpp::array<int,5u > arr(0);
    arr[0]=7;
    arr[1]=2;
    arr[2]=3;
    arr[3]=9;
    arr[4]=0;
 
    cout << "Array before sort : " << arr << endl;
    sort(arr.begin(),arr.end());
    cout << "Array after sort : "<< arr << endl;
 
    arr[5]=8;
    return 0;
}

到此这篇关于C++索引越界的解决方法的文章就介绍到这了,更多相关C++索引越界内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://www.cnblogs.com/AsanoLy/p/15093442.html

标签:

相关文章

热门资讯

yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
2021年耽改剧名单 2021要播出的59部耽改剧列表
2021年耽改剧名单 2021要播出的59部耽改剧列表 2021-03-05
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部