簡體   English   中英

什么決定了 STL 容器中的 max_size?

[英]What determines max_size in STL containers?

我試圖在 C 中重現 std::string 的行為,但有一件事我真的不知道該怎么做。 有一個max_size成員方法可以提供最大大小的字符串(或任何其他用於向量的 arrays 等),所以我的問題是我知道這個值可能取決於系統,那么容器如何確定這個數字? 我可以在 C 中得到它嗎?

什么決定了 STL 容器中的 max_size?

標准庫的實現者選擇它。 考慮到 API 和目標系統施加的限制,實施者應設計容器以支持盡可能大的尺寸。 容器的實現失敗,並且提供的分配器可能會施加額外的限制,理想情況下應該通過降低(因此更准確)的max_size來反映。

請注意, max_size在實踐中只是很少有用的值。 這是一個理論上的上限,實際上不一定可以達到......通常是因為 memory 是不夠的,至少在 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 源文件,其中包含由 ZF6F87C9FDCF8B3C3F07F93F1EE871 程序生成的常量。 生成部分顯然涉及到C++,但生成的源代碼將是純C,並且只能使用C編譯器進行編譯。

如果這不符合您的喜好,您可以 go 閱讀您選擇的 C++ 標准庫的實現文件,看看他們是如何實現max_size的,然后手動編寫 Z0D61F8370CAD1D412F570B84D14Z3E 源代碼。 這不涉及在任何時候編寫或編譯任何 C++,盡管它確實涉及讀取 C++。

max_size定義了容器在理論上可以針對該容器的特定實現具有的最大大小。

該數字不取決於操作系統或可用的 memory,而僅由容器的實現給出。

如果字符串容器(不兼容std::string )實現是這樣的:

struct string {
   unsigned char size;
   char *data;

   // … further functions …
};

那么max_size可能是指unsigned char可以表示的最大數字。

如果您的實現只是一個\0終止的字符串,沒有任何其他元信息。 那么max_size可能是指對於給定的目標體系結構,可以通過指針尋址的最大字節數。

所以max_size只是說,容器的實現方式將能夠處理max_size個元素。 但它不能保證操作系統能夠做到這一點。


對於std::string ,實現可以處理的最大字符數的上限size_type的最大數量和一些進一步的約束給出。

std::string本身的size_type由使用的分配器 ( std::allocator<CharT> ) 給出,默認為std::allocator_traits<Allocator>::size_type

對於std::allocatorsize_type裁判std::size_t

因此,對於std::stringmax_size上限std::size_t的最大值減去滿足字符串其他要求所需的值n

gcc-4.6.2libstdc++定義了關於max_size說明

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

以及相應的初始化

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 (不確定是否有任何更新的更新), max_size的值不會因調用而改變:

LWG 很清楚,max_size() 返回的值不會因調用而異。

因此,您可以使用eerorika的方法來獲取特定分配器的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM