符合标准的字符串是否可以长于SIZE_MAX字符?
我没有在C11标准中找到任何声明字符串不能超过SIZE_MAX
(其中SIZE_MAX
表示size_t
类型的最大值)字符的任何内容。 例如,如果size_max
很long
,并且在我的实现中有一个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_MAX
。 strlen(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;