简体   繁体   English

lower_bound()算法/ STL使用前置条件

[英]lower_bound() algorithm/STL usage preconditions

The code below returns erroneous results if compiled for 32bit Linux systems, and the same problem applies to 64bit systems, given large enough vectors. 如果为32位Linux系统编译,下面的代码会返回错误的结果,并且在给定足够大的向量的情况下,同样的问题也适用于64位系统。

Have the preconditions of lower_bound or STL in general been violated, and if so, where? 通常是否违反了lower_bound或STL的前提条件,如果是,那么在哪里?

I have been informed by STL sources that the size of the vector is cast to a signed type, which explains the behaviour. 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;
 }
}

Output: (Linux OS & Clang++ 7.0.0) 输出:( Linux OS和Clang ++ 7.0.0)

Vector maximal size: 4294967295 and actual size: 2415919104
Found value 2

Output: (Windows 10 OS & 32bit-msvc) 输出:(Windows 10 OS和32bit-msvc)

vector<T> too long

Update: While a fix for std::vector is under way, the problem persists for arrays allocated by 更新:虽然正在修复std :: vector,但是分配的数组仍然存在问题

auto p= new uint8_t[sz]; // 2.25 G entries

and the result depends on compiler & stdlib. 结果取决于编译器和stdlib。

In libstdc++ the function lower_bound(...) uses distance(...) , it starts with: 在libstdc ++中,函数lower_bound(...)使用distance(...) ,它以:

typedef typename iterator_traits<_ForwardIterator>::difference_type  _DistanceType;
_DistanceType __len = std::distance(__first, __last);
...

According to the Standard (23.2, [container.requirements]): 根据标准(23.2,[container.requirements]):

Expression: a.max_size() ; 表达式: a.max_size() ; return type: size_type ; 返回类型: size_type ; operational semantics: distance(begin(), end()) for the largest possible container 操作语义:最大可能容器的distance(begin(), end())

distance(...) returns difference_type (24.4.4, [iterator.operations]] distance(...)返回difference_type (24.4.4,[iterator.operations]]

 template<class InputIterator> typename iterator_traits<InputIterator>::difference_type distance(InputIterator first, InputIterator last); 

Hence, max_size() should return a value than can be represented using a signed type ( int32_t in the present case). 因此, max_size()应返回一个值,该值可以使用有符号类型(在本例中为int32_t )表示。 However, max_size() returns 4'294'967'295 . 但是, max_size()返回4'294'967'295 I guess this is a bug in libstdc++. 我想这是libstdc ++中的一个错误。

By the way, in Microsoft STL implementation max_size() returns 2'147'483'647 . 顺便说一句,在Microsoft STL实现中, max_size()返回2'147'483'647

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM