服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++索引越界的解决方法

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

2021-12-10 15:04Welcom to LyAsano’s blog! C/C++

本文主要介绍了C++索引越界的解决方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

避免"索引越界"错误的规则如下(针对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

延伸 · 阅读

精彩推荐
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29