[英]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::allocator
, size_type
裁判std::size_t
。
因此,對於std::string
, max_size
的上限是std::size_t
的最大值減去滿足字符串其他要求所需的值n
。
gcc-4.6.2
的libstdc++
定義了關於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.