2

我想知道如何为给定平台修复字符串长度的上限(在 C++ 中)。

我仔细检查了很多库,其中大多数都是任意定义的。GNU C++ STL(具有实验性 C++0x 特性的 STL)有一个明确的定义:

size_t npos = size_t(-1); /*!< The maximum value that can be stored in a variable of type size_t */
size_t _S_max_len = ((npos - sizeof(_Rep_base))/sizeof(_CharT) - 1) / 4; /*!< Where _CharT is a template parameter; _Rep_base is a structure which encapsulates the allocated memory */

以下是我对公式的理解:

  • size_t 类型必须保存分配给字符串的单元数(其中每个单元的类型为 _CharT)
  • 理论上,size_t 类型的变量可以取的最大值是可以分配的 1 字节(即 char 类型)单元的总数
  • 因此,先前的值减去跟踪分配的内存 (_Rep_base) 所需的开销是字符串中的最大单元数。将此值除以 sizeof(_CharT) 因为 _CharT 可能需要超过一个字节
  • 从前一个值中减去 1 以说明终止字符
  • 最后,除以 4。我完全不知道为什么!

我看了很多地方的解释,但在任何地方都找不到令人满意的地方(这就是为什么我一直在努力弥补它的原因!如果我错了,请纠正我!!)。

4

4 回答 4

2

来自 GCC 4.3.4 状态的 basic_string.h 中的注释:

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

特别要注意最后一行,“此外,此实施将这一数额减半。” 我认为这意味着除以四实际上是完全任意的。

我试图在basic_string.h 的签入日志中找到更多信息,但它只能追溯到 2000 年 10 月 5 日,并且该评论已经存在,如该修订版所示,我对该代码库不够熟悉知道文件在移动到当前位置之前可能在源树中的位置。

于 2010-04-06T18:33:30.850 回答
0

您可以创建一个包含std::string. 暴露你关心的接口功能。如果任何函数调用会使您的字符串超出您所需的最大长度,您可能会抛出异常或以其他方式触发错误。

这是一种实现目标的方法(在字符串上固定最大长度),而无需深入解读标准库实现的混乱。

于 2010-03-19T17:54:14.433 回答
0

如果您不介意在运行时检查,可以调用std::string::max_size,它返回字符串的最大可能长度。这不会为您的结果提供任何理由(而且我不知道/4GNU 代码中的原因),但它至少会给您一些明确的工作。

这不是一个静态函数,因此确定每个字符串的正确值可能需要一点小心和/或一些特定于系统的代码。(例如,VC++ 字符串看起来要遵循其分配器来获取此信息。这意味着不同的字符串可能具有不同的最大大小,如果它们使用不同的分配器,我想。)

于 2010-03-19T18:16:50.670 回答
0

实际限制可能远小于绝对限制。例如,内存分配将失败。实际限制不能真正提前知道。

于 2010-03-19T18:20:50.850 回答