C++编程调试秘笈----读书笔记(3)(一)

2014-11-24 08:38:17 · 作者: · 浏览: 3
三、索引越界
1、动态数组可以使用new,也可以用vector来动态创建
但是当下标的索引超过size的时候,new出来的数组对其进行更改的时候会有不确定的错误产生;vector提供了一个at(index)的函数,他通过抛出一个out_of_range异常执行边界检测
测试代码(vs2012+win7环境):
[cpp]
#include "stdafx.h"
#include "scpp_assert.h"
#include "iostream"
#include "vector"
#define SIZE 10
int _tmain(int argc, _TCHAR* argv[])
{
char *str = new char[SIZE];
str[SIZE + 1] = 'x';
std::vector arrayStr;
arrayStr.resize(SIZE);
arrayStr[11] = 'x';
return 0;
}
他的问题在于如果我们想执行这种安全检查,必须在访问数组元素的每个地方都严格地使用at()函数。显然这种做法会降低代码的效率,因此在完成了测试之后,我们可能想要速度更快的[]操作符在每处对他继续拧替换。但是,这样的替换对代码进行大量的修改。因此可以使用下面的方法(以解决不必使用at函数):
[cpp]
#ifndef __SCPP_VECTOR_H__
#define __SCPP_VECTOR_H__
#include "scpp_assert.h"
#include "vector"
namespace scpp
{
template
class vector : public std::vector
{
public:
typedef unsigned size_type;
public:
explicit vector(size_type n = 0) : std::vector(n){ }
vector(size_type n, const T& value) : std::vector(n, value){ }
template vector(InputIterator first, InputIterator last)
: std::vector(first, last){ }
T &operator[] (size_type index)
{
SCPP_TEST_ASSERT(index < std::vector::size(),
"Index " << index << " must be less than "
<< std::vector::size());
return std::vector::operator [](index);
}
const T &operator[] (size_type index) const
{
SCPP_TEST_ASSERT(index < std::vector::size(),
"Index " << index << " must be less than "
<< std::vector::size());
return std::vector::operator [](index);
}
};
}; // namespace scpp
template
inline std::ostream &operator << (std::ostream &os, const scpp::vector& v)
{
for (unsigned index = 0; index < v.size(); ++index)
{
os << v[index];
if (index + 1 < v.size())
{
os << " ";
}
}
return os;
}
#endif
测试代码(vs2012+win7环境):
[cpp]
#include "stdafx.h"
#include "scpp_assert.h"
#include "iostream"
#include "scpp_vector.h"
#define SIZE 10
int _tmain(int argc, _TCHAR* argv[])
{
scpp::vector str(SIZE, 'z');
std::cout << str << std::endl;
str[20] = 'x';
return 0;
}
在stdafx.h中打开调试开关:
[cpp]
#pragma once
#include "targetver.h"
#include
#include
// TODO: 在此处引用程序需要的其他头文件
/*#define SCPP_THROW_EXCEPTION_ON_BUG*/
#define SCPP_TEST_ASSERT_ON
2、静态数组:
scpp::vector vect(SIZE)他的效果与静态数组完全相同,但问题在于效率。静态数组是在堆栈上分配内存,而vector模板输在构造函数中使用new操作符分配的,速度比较慢,所以这里有array模板:
scpp_array.h:
[cpp]
#ifndef __SCPP_ARRAY_H__
#define __SCPP_ARRAY_H__
#include "scpp_assert.h"
namespace scpp
{
template
class array
{
public:
typedef unsigned size_type;
public:
array(){ }
explicit array(const T& initialValue)
{
for (size_type index = 0; index < N; ++index)
{
data_[index] = initialValue;
}
}
size_type size() const { return N; }
T& operator[](size_type index)
{
SCPP_TEST_ASSERT(index < N,
"Index " << index << " must be less than " << N);
return data_[index];
}
const T& operator[](size_type index) const
{
SCPP_T