对std::vector的最大大小感到困惑



我在std::vector的代码中遇到了一个问题,给了我:vector<T> too long。这里我用的是char类型的向量。代码是处理3D(断层扫描)图像,所以我有很多体素。我在windows上使用VS编译器与在Mac上使用CLANG有完全相同的问题,尚未测试gcc。

为了检查这个问题,我添加了以下行:

printf("max vector size %un", v.max_size() );
printf("PTRDIFF_MAX %u, INTMAX_MAX %un", PTRDIFF_MAX, INTMAX_MAX );

这给了我:

max vector size 4294967295
PTRDIFF_MAX 4294967295, INTMAX_MAX 4294967295

我有两个问题:

  1. 为什么最大值这么小?它看起来像一个uint32的最大值。我希望它在size_t的范围内,应该是18446744073709551615,对吧?
  2. 为什么当我的向量超过2147483648(即规定最大值的一半)值时,我得到vector<T> too long?
  3. [编辑]

一些反应:

  • 谢谢你指出我的打印错误。我已经转换为std::cout,现在我得到(这在64位系统上更有意义):

    max_size: 9223372036854775807
    PTRDIFF_MAX: 9223372036854775807
    INTMAX_MAX: 9223372036854775807
    
  • vector<T> too long错误是运行时错误

  • 我把它追溯到我调整矢量

    大小的那一行
  • 当我使用uint32_t而不是char的向量时,问题出现在相同的向量长度(内存使用量的4倍)。

  • 我有足够的RAM,但是,我不知道分配如何在调整大小请求时工作。也许,没有足够大的连续可用的RAM块?

为什么最大值这么小?它看起来像一个uint32的最大值。

这是在32位系统上预期的。

我希望它在size_t的范围内,应该是18446744073709551615,对吧?

如果PTRDIFF_MAX是4294967295,那么我发现SIZE_MAX将多达18446744073709551615,这令人惊讶。也就是说,我也会发现PTRDIFF_MAX是4294967295。

您将看到令人惊讶且无意义的输出,因为程序的行为是未定义的,这是因为您使用了错误的格式说明符。%u用于无符号整型,且仅用于无符号整型。%td表示std::ptrdiff_t,PRIdMAX宏扩展为std::intmax_t,%zu表示std::size_t

我建议学习使用c++的iostreams。使用它们并不像使用C标准I/o时那样容易意外导致未定义行为。

为什么当我的向量超过2147483648(即规定最大值的一半)值时,我得到的向量太长?

我不知道怎么得到"向量太长"意味着,但通常情况下,您没有整个地址空间可供您的程序使用。很有可能其中一半是留给内核的。

max_size没有必要考虑到这样的系统限制,这是一个在实践中通常无法达到的理论极限。

最新更新