c++ - lower_bound() 算法/STL 使用前提条件

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

如果为 32 位 Linux 系统编译,下面的代码会返回错误的结果,如果 vector 足够大,同样的问题也适用于 64 位系统。

通常是否违反了 lower_bound 或 STL 的先决条件,如果违反了,在哪里?

我从 STL 消息来源获悉, vector 的大小被强制转换为有符号类型,这解释了行为。

// 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)

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

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

vector<T> too long

更新:虽然对 std::vector 的修复正在进行中,但对于由

分配的数组,问题仍然存在
auto p= new uint8_t[sz]; // 2.25 G entries 

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

最佳答案

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

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]]

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

关于c++ - lower_bound() 算法/STL 使用前提条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51907247/

相关文章:

c++ - MFC 中的矩形

c++ - 设置 vector of int 指针,指向 int vector 的元素

c++ - Windows 是否支持从内存运行程序?

linux - bash 脚本中的一个特定命令在由 cron 运行时不起作用,所有其他命令都可以

python - 通过 Python 选择要播放的音频设备

c++ - .NET 和 native C++ 应用程序之间通信的最佳方式

linux - 将过滤器附加到 linux 中的 tcp 套接字

c++ - 使用 STL 算法查找集合中的前两个不相邻元素

c++ - std::set with std::pair - 如何为元素编写比较器

c++ - 在 C++ 中查找函数 <algorithm>