c – lower_bound()算法/ STL使用前置条件
作者:互联网
如果为32位Linux系统编译,下面的代码会返回错误的结果,并且在给定足够大的向量的情况下,同样的问题也适用于64位系统.
通常是否违反了lower_bound或STL的前提条件,如果是,那么在哪里?
STL消息来源告诉我,向量的大小被转换为有符号类型,这解释了行为.
// compile with and without -m32 switch
#include<algorithm>
#include<iostream>
#include<stdexcept>
#include<vector>
using namespace std;
int main() {
try {
vector<uint8_t> v((1ULL << 28) * 9, 2); // 2.25 G entries
v.back() = 3; // the last of which is greater
cout<< "Vector maximal size: "<<v.max_size()<< " and actual size: " << v.size() <<endl;
uint8_t val=3;
auto x= lower_bound(v.begin(), v.end(), val );
if (x!=v.end() && !( val< *x ) ) {
cout << "Found value " << int(*x) << endl;
} else {
cout << "Not Found " << endl;
}
} catch (exception const & ex){
cerr<< ex.what()<<endl;
}
}
输出:( Linux OS& Clang 7.0.0)
Vector maximal size: 4294967295 and actual size: 2415919104 Found value 2
输出:(Windows 10 OS& 32bit-msvc)
vector<T> too long
更新:虽然正在修复std :: vector,但是分配的数组仍然存在问题
auto p= new uint8_t[sz]; // 2.25 G entries
结果取决于编译器& STDLIB.
解决方法:
在libstdc中,函数lower_bound(…)使用距离(…),它以:
typedef typename iterator_traits<_ForwardIterator>::difference_type _DistanceType;
_DistanceType __len = std::distance(__first, __last);
...
根据标准(23.2,[container.requirements]):
Expression:
a.max_size()
; return type:size_type
; operational semantics:distance(begin(), end())
for the largest possible container
distance(…)返回difference_type(24.4.4,[iterator.operations]]
06001
因此,max_size()应返回一个值,该值可以使用有符号类型(在本例中为int32_t)表示.但是,max_size()返回4’294’967’295.我想这是libstdc中的一个错误.
顺便说一句,在Microsoft STL实现中,max_size()返回2’147’483’647.
标签:c-2,linux,stl,c17,stl-algorithm 来源: https://codeday.me/bug/20190622/1262000.html