我在C11标准中没有找到任何内容,表明字符串不能超过SIZE_MAX
(其中SIZE_MAX
表示size_t
类型)字符的最大值。例如。如果size_max
是long
,并且在我的实现中有一个long long
类型,它严格大于long
,那么我可以使用{{定义和索引这样的字符串1}}。
然而,这意味着一些不寻常的情况:例如,long long
可能无法返回字符串的实际大小,因为结果将在结尾转换为strlen
,因此例如,长度为size_t
的字符串将被报告为大小为0。例如,这会违反标准,从而防止这些字符串存在吗?作为参考,7.24.6.3只说:
7.24.6.3 strlen函数
概要
SIZE_MAX+1
#include <string.h>
描述
strlen函数计算s指向的字符串的长度。
返回
strlen函数返回终止空字符前面的字符数。
我是否遗漏了某些东西,或者这是否完全有效(在符合标准的C17执行中)?
答案 0 :(得分:3)
从[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
。
答案 1 :(得分:0)
让我们把一些规格放在一起。
string 是一个连续的字符序列,由第一个空字符终止并包含第一个空字符。 C11§7.1.11(我的重点)
当应用
sizeof
...具有数组类型的操作数时,结果是数组中的总字节数.... C11§6.5.3.44
size_t
这是sizeof
运算符的结果的无符号整数类型; C11§7.192
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;