C++索引越界的解决方法
作者:Welcom to LyAsano’s blog! 时间:2023-07-21 21:53:17
避免"索引越界"错误的规则如下(针对C++):
不要使用静态或动态分配的数组,改用array或vector模板
不要使用带方括号的new和delete操作符,让vector模板为多个元素分配内存
使用scpp::vector代替std::vector,使用scpp::array代替静态数组,并打开安全检查(自动在使用下标访问提供了索引边界检查)
C++中创建类型T的对象的数组方式如下:
#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>,并重载<< 、[]运算符,提供一个能够捕捉越界访问错误的实现。
实现代码和测试如下:
//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模板(同样也是栈内存),实现代码和测试如下:
//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;
}
来源:https://www.cnblogs.com/AsanoLy/p/15093442.html
标签:C++,索引,越界
0
投稿
猜你喜欢
c#基于WinForm的Socket实现简单的聊天室 IM
2021-11-27 04:47:57
C#遍历得到checkboxlist选中值和设置选中项的代码
2022-10-25 20:52:22
分析Android 11.0Settings源码之主界面加载
2021-05-25 23:15:02
Android使用Retrofit2.0技术仿微信发说说
2021-05-24 03:09:18
springboot+jersey+tomcat实现跨域方式上传文件到服务器的方式
2023-08-16 10:26:45
java递归算法实例分析
2022-02-09 07:59:17
SpringBoot中多环境配置和@Profile注解示例详解
2023-11-29 05:39:04
springboot 使用自定义的aspect的示例代码
2023-08-06 08:55:14
SpringBoot整合Echarts实现用户人数和性别展示功能(详细步骤)
2023-02-22 00:31:59
maven下载jar包改用阿里云maven库的方法
2023-02-13 07:41:58
Android双向选择控件DoubleSeekBar使用详解
2022-02-13 10:05:29
C#实现图形区域组合操作的方法
2023-05-01 19:08:21
SpringBoot整合Shiro框架,实现用户权限管理
2021-10-27 00:03:02
C# goto语句的具体使用
2021-07-22 22:26:22
C#调用百度翻译实现翻译HALCON的示例
2022-06-08 23:33:50
c#多进程通讯的实现示例
2022-09-06 02:43:23
android横竖屏切换时候Activity的生命周期
2021-12-10 16:02:36
【java 多线程】守护线程与非守护线程的详解
2023-11-29 01:35:29
Java同步函数代码详解
2022-10-13 23:22:03
C#中实现网段扫描的代码
2022-05-09 03:54:33