代码之家  ›  专栏  ›  技术社区  ›  Evan Teran

为什么std::string::max_size()不等于std::string::allocator::max_size()

  •  5
  • Evan Teran  · 技术社区  · 16 年前

    最近我注意到下面的说法是不正确的 std::string s

    s.max_size() == s.get_allocator().max_size();
    

    默认情况下,我觉得这很有趣 std::string 将使用 std::allocator<char> size_type(-1) (是的,我知道我假设的是2的补码,但这与实际问题无关)。我知道,实际限制将大大低于这一点。在典型的32位x86系统上,内核将占用2GB(也许1GB)的地址空间,留下一个更小的实际上限。

    无论如何,GNU libstdc++ std::basic_string<>::max_size() 似乎返回相同的值,而不管它使用的分配器是什么(类似 1073741820 ).

    所以问题依然存在,为什么不呢 标准::基本字符串<>::最大尺寸() get_allocator().max_size() ? 在我看来,这是假设的上限。如果分配不足,它只会抛出一个 std::bad_alloc ,那为什么不试试呢?

    这比其他任何事情都更令人好奇,我只是想知道为什么在至少这一个实现中这两个是分开定义的。

    3 回复  |  直到 16 年前
        1
  •  10
  •   Kirill V. Lyadvinsky    16 年前

    在里面 Microsoft Connect

    根据我们对该标准的解释,我们已经通过设计解决了这个问题,该标准没有清楚地解释max_size()的预期用途。分配器max_size()被描述为“可以有意义地传递给X::allocate()的最大值”(C++03 20.1.5[lib.Allocator.requirements]/表32),但容器max_size()被描述为“可能的最大容器的大小”(23.1[lib.container.requirements]/表65)。没有任何内容描述是否或如何从分配器max_size()派生容器max_size()。多年来,我们的实现直接从分配器max_size()派生容器max_size(),然后将此值用于溢出检查等。本标准的其他解释,如您的解释,是可能的,但对我们来说并不明确正确。该标准的措辞肯定会从这里的澄清中受益。除非发生这种情况,否则我们决定保持当前的实现不变,原因有两个:(1)其他客户可能依赖于我们当前的行为,(2)max_size()根本不买任何东西。最多,使用分配器的东西(比如容器)可以使用分配器max_size()来预测allocate()何时会失败——但简单地调用allocate()是一个更好的测试,因为分配器随后将决定是否释放内存。使用容器的东西可以使用container max_size()来保证size()的大小,但更简单的保证是size_类型的范围。

    另外 here

    因此,您的问题“为什么…”的答案是,该标准没有明确解释max_size()的预期用途。

        2
  •  4
  •   Sinan Ünür    16 年前

    我不完全确定,但据我所知 std::basic_string 在当前标准中不限于将字符串存储在连续内存中。例如,它可以将其存储在多个块中。然后,每个这样的块被限制为 std::allocator::max_size() 但总数可能比这还要大。

    STL容器似乎也是如此。毕竟

        3
  •  1
  •   UncleBens    16 年前

    GCC的实现对它们的计算方式提出了意见 max_size (必须减去内部内务管理对象的大小,该对象被分配为带有字符串的单个块),然后将其相加 max_size() 返回其中的四分之一。没有给出任何理由,所以这可能只是一个安全裕度?(它还应该提供一个rope类,可能用于如此大的字符串?)

    最大尺寸() 返回小于1的值 allocator.max_size()