为了账号安全,请及时绑定邮箱和手机立即绑定

C中数组的最大大小是多少?

/ 猿问

C中数组的最大大小是多少?

C
慕虎7371278 2019-11-14 10:01:55

我知道硬件会限制程序执行期间分配的内存量。但是,我的问题与硬件无关。假设对内存量没有限制,那么对数组没有限制吗?



查看完整描述

3 回答

?
德玛西亚99

C中的数组大小没有固定限制。


任何单个对象(包括任何数组对象)的大小都受SIZE_MAXtype的最大值限制,该最大值size_t是sizeof运算符的结果。(尚不清楚C标准是否允许大于SIZE_MAX字节的对象,但实际上不支持此类对象;请参见脚注。)由于SIZE_MAX由实现决定,并且不能由任何程序修改,因此施加了SIZE_MAX字节的上限对于任何单个对象。(这是一个上限,而不是至少一个上限;实现可能并且通常确实会施加较小的限制。)


类型的宽度(void*通用指针类型)对正在执行的程序中所有对象的总大小施加上限(可能大于单个对象的最大大小)。


C标准在这些固定大小上施加下限,但不施加上限。没有符合标准的C实现可以支持无限大小的对象,但是原则上它可以支持任何有限大小的对象。上限由各个C实现,它们运行的环境以及物理(而不是语言)强加。


例如,一个符合的实现可能SIZE_MAX等于2 1024 -1,这意味着它原则上可以具有以下对象:1797693134862315907729305190789024733617976978942306572734300811577326758055009631327084772402406026021120113879871393357658789768814416622492847430639474124377767893424865327608754342345638723456365434562253654355234561842345127184275184275184275285184275184354285板机机百万次元365365-365竞猜网-体验吧


祝您好运,找到实际上支持此类对象的硬件。


脚注:没有明确的规则,即任何对象都不能大于SIZE_MAX字节。您无法将sizeof运算符有效地应用于这样的对象,但是像任何其他运算符一样,它sizeof可能会溢出。这并不意味着您无法对此类对象执行操作。但是实际上,任何理智的实现都会size_t足够大,足以表示它支持的任何对象的大小。


查看完整回答
反对 回复 2019-11-14
?
慕神8447489

C99 5.2.4.1“翻译限制”最小尺寸


该实现应能够翻译和执行至少一个程序,该程序包含以下每个限制的至少一个实例:13)


对象中的65535字节(仅在托管环境中)

13)实施过程中应尽可能避免施加固定的翻译限制。


这表明一个符合标准的实现可能拒绝编译一个对象(包括数组),其short字节数多。


PTRDIFF_MAX 似乎是静态数组对象的实际限制


C99标准6.5.6加法运算符说:


9当减去两个指针时,两个指针均应指向同一数组对象的元素,或者指向数组对象的最后一个元素之后的元素;结果是两个数组元素的下标不同。结果的大小由实现定义,并且其类型(有符号整数类型)ptrdiff_t在<stddef.h>标头中定义。如果结果无法在该类型的对象中表示,则该行为未定义。


对我来说,这意味着比ptrdiff_t理论上允许的数组大,但是您不能便携地使用它们的地址差。


因此,也许出于这个原因,GCC似乎将您限制为ptrdiff_t。在以下位置也提到了这一点:为什么数组的最大大小“太大”?


我已经通过以下经验验证了这一点main.c:


#include <stdint.h>


uint8_t a[(X)];


int main(void) {

    return 0;

}

然后在Ubunbu 17.10中:


$ arm-linux-gnueabi-gcc --version

arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0

Copyright (C) 2017 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


$ printf '

> #include <stdint.h>

> PTRDIFF_MAX

> SIZE_MAX

> ' | arm-linux-gnueabi-cpp | tail -n2

(2147483647)

(4294967295U)

$ PTRDIFF_MAX == 2147483647 == 2^31 - 1

$

$ # 2lu << 30 == 2^31 == PTRDIFF_MAX + 1

$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30)' main.c

a.c:5:9: error: size of array ‘a’ is too large

 uint8_t a[(X)];

         ^

$

$ # PTRDIFF_MAX

$ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30) - 1lu' main.c

$


查看完整回答
反对 回复 2019-11-14
?
慕盖茨1488219

指针的大小将限制您能够访问的内存。即使硬件提供了对无限内存的支持,但是如果您能够使用的最大数据类型是64位,则您将只能访问2 ^ 64字节的内存。


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信