符合标准的字符串是否可以长于SIZE_MAX字符?

我没有在C11标准中找到任何声明字符串不能超过SIZE_MAX (其中SIZE_MAX表示size_t类型的最大值)字符的任何内容。 例如,如果size_maxlong ,并且在我的实现中有一个long long类型,它严格地大于long ,那么我可以使用long long定义和索引这样的字符串。

但是,这意味着一些不寻常的情况:例如, strlen可能无法返回字符串的实际大小,因为结果将在结尾处转换为size_t ,因此将报告长度为SIZE_MAX+1的字符串为例如,大小为0。 例如,这会违反标准,从而防止这些字符串存在吗? 作为参考,7.24.6.3仅表示:

7.24.6.3 strlen函数

概要

#include

size_t strlen(const char *s);

描述

strlen函数计算s指向的字符串的长度。

返回

strlen函数返回终止空字符前面的字符数。

我是否遗漏了某些东西,或者这对C11(符合标准的实施)是否完全有效?

从[6.5.3.4 sizeof和alignof运算符]:

4当sizeof应用于具有char,unsigned char或signed char(或其限定版本)类型的操作数时,结果为1.当应用于具有数组类型的操作数时,结果为总字节数在数组中。 102)当应用于具有结构或联合类型的操作数时,结果是此类对象中的总字节数,包括内部和尾部填充。

5两个运算符的结果值是实现定义的,其类型(无符号整数类型)是size_t,在"stddef.h" (和其他标题)中定义。

因此,任何数组的大小都不能超过size_t可以容纳的数量,因此字符串的大小不能超过SIZE_MAX

编辑:使用calloc ,请参见[7.22.3.2 calloc函数]:

calloc函数为nmemb对象数组分配空间,每个对象的大小都是size。 空间初始化为所有位零。

它为数组分配空间,但数组大小必须适合size_t ,因此不能使用calloc分配超过SIZE_MAX 。 如果你这样做,它必须返回NULL

让我们把一些规格放在一起。


字符串是由第一个空字符终止并包括第一个空字符的连续字符序列 。 C11§7.1.11(我的重点)


当应用sizeof …具有数组类型的操作数时,结果是数组中的总字节数…. C11§6.5.3.44

size_t ,它是sizeof运算符结果的无符号整数类型; C11§7.1922

size_t的限制是SIZE_MAX C11 7.20.3 2


如果我们只为字符数组使用字符数组对象或分配的内存,则最长的字符串大小为SIZE_MAXstrlen(x_big)的最大返回值是SIZE_MAX - 1


如果代码成功使用以下代码,那么代码冒险了很多,在这种情况下, 字符串可能构造得比SIZE_MAX ,但我怀疑calloc()将首先返回NULL(char *) ptr将失败。

 double *ptr = calloc(SIZE_MAX, sizeof *ptr); assert(ptr); char *s_waybig = (char *) ptr;