代码之家  ›  专栏  ›  技术社区  ›  Fayeure

什么决定STL容器中的最大大小?

c++
  •  4
  • Fayeure  · 技术社区  · 5 年前

    我试图在C中重现std::string的行为,但有一件事我真的不知道怎么做。有一个 max_size 为字符串(或向量的任何其他数组等)提供最大大小的成员方法可以有,所以我的问题是我知道这个值可以依赖于系统,那么容器如何确定这个数字呢?我能用C写吗?

    3 回复  |  直到 5 年前
        1
  •  5
  •   eerorika    5 年前

    什么决定STL容器中的最大大小?

    标准库的实现者选择了它。考虑到API和目标系统施加的限制,实现者应该设计容器来支持尽可能大的大小。容器的实现破坏了容器,并且提供的分配器可能会施加额外的限制,理想情况下,这些限制应该通过降低的(从而更准确)来反映 max_size .

    请注意 最大尺寸 在实践中很少有用。这是一个理论上限,实际上不一定可以达到。。。通常是因为内存不足,至少在64位系统上是这样。它用于早期检测用户输入(然后相应地抛出异常)。

    我能用C写吗?

    您可以定义一个常量外部变量,并在c++翻译单元中对其进行初始化。例子:

    // common_header.h
    // add header guard here
    #include <stdlib.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    extern const size_t cpp_string_max_size;
    extern const size_t cpp_vector_int_max_size;
    
    #ifdef __cplusplus
    }
    #endif
    
    // source.cpp
    #include "common_header.h"
    #include <string>
    #include <cstdlib>
    #include <vector>
    
    const std::size_t cpp_string_max_size = std::string{}.max_size();
    const std::size_t cpp_vector_int_max_size = std::vector<int>{}.max_size();
    

    然后,使用C++编译器编译C++翻译单元,并将其与C程序链接。


    我正在寻找一种不涉及任何C语言的方法++

    根据您所说的“任何C++”的含义,您可以使用元编程:编写一个C++程序,生成一个C源文件,其中包含由C++程序生成的常数。生成部分显然涉及C++,但生成的源代码将是纯C的,并且只能使用C编译器进行编译。

    最大尺寸 ,并手动编写C源代码。这并不涉及在任何时候编写或编译任何C++,尽管它确实涉及阅读C++。

        2
  •  3
  •   t.niese    5 年前

    max_size 定义了容器理论上对于该容器的特定实现可以具有的最大大小。

    该数字不取决于操作系统或可用内存,而仅由容器的实现给出。

    如果 你的 (不是 std::string

    struct string {
       unsigned char size;
       char *data;
    
       // … further functions …
    };
    

    然后 最大尺寸 unsigned char 可以表示。

    如果您的实现只是一个 \0 终止的字符串,没有任何其他元信息。然后 对于给定的目标体系结构,可能是指可以通过指针寻址的最大字节数。

    所以 最大尺寸 最大尺寸 元素数量。但这并不能保证操作系统能够做到这一点。


    对于 标准::字符串 这个 上限 实现可以处理的最大字符数由 size_type 以及一些进一步的限制。

    这个 size_type 对于 标准::字符串 其本身由使用的分配器给出( std::allocator<CharT> )默认为 std::allocator_traits<Allocator>::size_type .

    对于 std::allocator 这个 size\u类型 仲裁人 std::size_t

    所以对于一个 标准::字符串 这个 上限 最大尺寸 是的最大值 标准::size\u t 减去一个值 n

    这个 libstdc++ 属于 gcc-4.6.2 定义 says this 关于 最大尺寸 :

    // The maximum number of individual char_type elements of an
    // individual string is determined by _S_max_size. This is the
    // value that will be returned by max_size().  (Whereas npos
    // is the maximum number of bytes the allocator can allocate.)
    // If one was to divvy up the theoretical largest size string,
    // with a terminating character and m _CharT elements, it'd
    // look like this:
    // npos = sizeof(_Rep) + (m * sizeof(_CharT)) + sizeof(_CharT)
    // Solving for m:
    // m = ((npos - sizeof(_Rep))/sizeof(CharT)) - 1
    // In addition, this implementation quarters this amount.
    static const size_type  _S_max_size;
    static const _CharT _S_terminal;
    

    以及相应的 initialization

    template<typename _CharT, typename _Traits, typename _Alloc>
      const typename basic_string<_CharT, _Traits, _Alloc>::size_type
      basic_string<_CharT, _Traits, _Alloc>::
      _Rep::_S_max_size = (((npos - sizeof(_Rep_base))/sizeof(_CharT)) - 1) / 4;
    

    据此 197. max_size() underspecified (不确定是否有更新),的值 最大尺寸 不会在呼叫之间更改:

    LWG很清楚,max_size()返回的值不能在调用之间更改。

    eerorika 为特定分配器获取该值。