- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在过去十年左右的时间里,C 和 C++ 程序员因经常未能执行正确的边界检查而遭受打击,尤其是在字符串上。这些故障通常会导致主要软件产品出现严重的安全问题。由于缓冲区溢出的不安全性变得广为人知,建立适当的边界检查的动力使许多程序员远离了传统的缓冲区和字符串操作函数,如 strcpy()
。和 sprintf()
至少部分是因为这些函数倾向于通过对目标缓冲区的大小进行假设来引发缓冲区溢出问题。 STL 类型的优点之一,如 std::string
和 std::vector
是他们对缓冲区访问的强大控制。
但是有一件事让我很困惑。 <algorithms>
中许多最广泛使用的功能C++ 头文件似乎积极地乞求溢出滥用:具体来说,那些采用 begin
的函数没有匹配 end
的迭代器(尤其是 InputIterator)迭代器。例如:
template <class InputIterator, class OutputIterator>
OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperation op);
template <class ForwardIterator1, class ForwardIterator2>
bool is_permutation (ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2);
最后一个例子——is_permutation()
尤其具有指导意义。 copy()
和 transform()
很好理解,因此 C++ 程序员应该知道在调用这些函数之前手动检查输出容器的边界或使用类似back_inserter
的东西确保输出容器根据需要增长。因此,可以证明尽管 copy()
和 transform()
可以被滥用,任何东西都可以,而且程序员可以很容易地接受关于使用这些函数的最佳实践的教育。
is_permutation()
是一个棘手的案例。看看上面的函数声明,您会假设第二个范围(以 first2
开头的范围)的大小是多少?第二个范围是否需要与第一个范围大小相同,或者不小于,或者不大于?我敢打赌,这些问题的简单答案不会浮现在您的脑海中。对于大多数程序员来说,“排列”的概念不如复制的概念舒服和熟悉。因此似乎相对容易获得 is_permutation()
错误并以一种或另一种方式溢出缓冲区。
“快看!”我听到你说。嗯,是的,当然。但是,如果程序员记住他们应该记住的所有内容并查找其他所有内容,那么我们就不会有错误和安全漏洞,对吗?
那为什么不is_permutation()
和类似的功能(即采用所有输入迭代器但不是每个范围的完整开始-结束迭代器对的函数)需要所有输入范围的完整开始-结束对? (请注意,例如 lexicographical_compare()
,确实满足此要求。)像 is_permutation()
这样的功能吗?实际上并没有我想象的那么不安全?
最佳答案
大多数语言本质上都是不安全的,正确使用它取决于程序员。程序员必须在调用函数之前知道所使用的参数是否正确。
此外,在某些情况下,例如 copy
,它允许在开放范围上使用前向迭代器。例如:
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout," "));
没有对应的迭代器来标记流的结束,流真的没有尽头,可以不断的往里面加。
关于c++ - 为什么像 std::is_permutation() 这样的函数本质上不是不安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17582412/
我了解了 NodeJS 的非阻塞特性,以及 I/O 操作如何实现非阻塞。我创建了一个简单的测试来证明这一点 var request = require('request'); var http = r
我是一名优秀的程序员,十分优秀!