文/刘涛
四、C++标准库中的边界检查
默认情况,C++标准库中大量的容器对象和迭代对象没有提供边界检查。例如,矢量的下标操作符通常是一个比较快,但有潜在的危险性的操作单独元素的方法。如果你正在寻找得到确认检查的操作方法,你可以转向"at"方法。安全性的增加是以牺牲性能为代价的。当然,绝大情况下性能的降低是可以忽略不计的,但是对于性能要求第一位的代码来说,这可能是非常有害的,思考一下下面的简单函数:
void PrintAll(const std::vector& numbers) { for (size_t index = 0; index < numbers.size(); ++index) { std::cout << numbers[index] << std::endl; } } void PrintN(const std::vector& numbers, size_t index) { std::cout << numbers.at(index) << std::endl; } |
PrintAll函数使用了下标操作符,因为索引由函数控制,并且可以确认是安全的。另一方面,PrintN函数不能保证索引的有效性,所以它使用了更安全的"at"方法来代替。当然,并不是所有的容器的存取操作都象这么简洁明了。
在保证C++标准库的安全特性的同时,Visual C++2005继续坚持并在很多情况下改进了C++标准库的运行特性,同时提供了调节C++标准库安全性的特色。一项受人欢迎的改进是在调试版本中添加了范围检查,这对你的发行版本性能并不构成影响。但这确实帮助你在调试阶段捕获越界错误,甚至是使用传统上不安全的下标操作符的代码。
不安全的函数,象vector的下标操作算子,和其他的函数,象它的front函数,如果不恰当的调用,通常会导致不明确的行为。如果你幸运的话,它将很快导致一个存取冲突,这将使你的应用程序崩溃。如果你不那么走运的话,它可能默默地持续运转并导致不可预知的副效应,这将破坏数据并可能被进攻者利用。为了保护你的发行版本的应用程序,Visual C++2005引入了_SECURE_SCL符号,用来给那些非安全的函数添加运行时检查。象下面的代码那样在你的应用程序中简单地定义这个符号可以添加额外的实时检查并阻止不确切的行为。
紧记定义这个符号对你的程序冲击很大,大量的合法的,但是具有潜在非安全的操作将在编译时将无法通过,以避免在运行时出现潜在BUG。思考下面的使用Copy运算的例子:
std::copy(first, last, destination); |
[上一页] [1] [2] [3] [4] [5] [6] [下一页]