【问题标题】:lower_bound() algorithm/STL usage preconditionslower_bound() 算法/STL 使用前提条件
【发布时间】:2018-08-18 09:37:34
【问题描述】:

如果为 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 操作系统和 Clang++ 7.0.0)

向量最大大小:4294967295 实际大小:2415919104
发现值 2

输出:(Windows 10 操作系统和 32 位 msvc)

向量太长了

更新:虽然正在修复 std::vector,但问题仍然存在于分配的数组中

自动 p= 新 uint8_t[sz]; // 2.25 G 条目 

结果取决于编译器和标准库。

【问题讨论】:

  • v.size() &gt; v.max_size() 在你的编译中吗?
  • 不,Linux max_size()=4G 太大,微软 STL 是对的。它会抛出 bad_alloc 吗?
  • 它抛出 std::length_error ([vector.capacity], reserve(): Throws: length_error if n &gt; max_size())。

标签: c++ linux stl c++17 stl-algorithm


【解决方案1】:

在 libstdc++ 中,函数 lower_bound(...) 使用 distance(...),它以:

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

根据标准(23.2,[container.requirements]):

表达式:a.max_size();返回类型:size_type;操作语义:distance(begin(), end()) 表示可能的最大容器

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

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

因此,max_size() 应该返回一个可以使用有符号类型表示的值(在本例中为int32_t)。但是,max_size() 返回4'294'967'295。我猜这是 libstdc++ 中的一个错误。

顺便说一句,在 Microsoft STL 实现中,max_size() 返回 2'147'483'647

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多