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

时间:2017-01-26 09:24:33

标签: c string language-lawyer c11

我在C11标准中没有找到任何内容,表明字符串不能超过SIZE_MAX(其中SIZE_MAX表示size_t类型)字符的最大值。例如。如果size_maxlong,并且在我的实现中有一个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执行中)?

2 个答案:

答案 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_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;