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

Nyx*_*yxm 45 c arrays

我知道硬件将限制程序执行期间分配的内存量.但是,我的问题是不考虑硬件.假设内存量没有限制,那么阵列没有限制吗?

Kei*_*son 42

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

任何单个对象(包括任何数组对象)的大小都受SIZE_MAX类型的最大值的限制size_t,这是sizeof运算符的结果.(目前还不完全清楚C标准是否允许大于SIZE_MAX字节的对象,但实际上这些对象不受支持;参见脚注.)由于SIZE_MAX是由实现决定的,并且不能被任何程序修改,因此强加了SIZE_MAX字节的上限对于任何单个对象.(这是一个上限,而不是一个上限;实现可能,通常会,施加更小的限制.)

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

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

例如,一致的实现可以具有SIZE_MAX等于2 1024 -1,这意味着它可以在原理上有对象高达179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215个字节.

祝你找到真正支持这些对象的硬件.

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

  • @caot:您的数组是在没有“static”关键字的函数内定义的,因此它具有自动存储持续时间。在大多数实现中,此类对象是在堆栈上分配的。您的系统可能限制了堆栈的大小。使用`static`,或者全局定义它,或者使用`malloc()`。 (2认同)

Cir*_*四事件 8

C99 5.2.4.1"翻译限制"最小尺寸

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

  • 对象中的65535个字节(仅限托管环境中)

13)实施应尽可能避免强加固定的翻译限制.

这表明一致的实现可以拒绝编译具有多于short字节的对象(包括数组).

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

C99标准6.5.6添加剂运营商说:

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

这对我来说意味着大于ptrdiff_t理论上允许的数组,但是你不能把它们的地址区别开来.

所以也许是因为这个原因,海湾合作委员会似乎只限制你ptrdiff_t.这也在下面提到:为什么数组的最大大小"太大"?

我凭经验证实了这一点main.c:

#include <stdint.h>

uint8_t a[(X)];

int main(void) {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后在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
$
Run Code Online (Sandbox Code Playgroud)

也可以看看


gre*_*reg 6

理论上,64位机器最多可以处理2 ^ 64字节的内存.

  • @Durandal,http://www.wolframalpha.com/input/?i = number + of + atoms + in + thethearth表示地球上有1x10 ^ 50个原子,2 ^ 64是1*10 ^ 25.我*可能过于乐观了.:)没想到这一点...... (5认同)
  • @Durandal - 我知道你2年前做过这个评论,但是2 ^ 64字节只有16艾字节,这是"仅"2 ^ 30 16GB RAM模块(或大约10亿).假设一个RAM棒的重量约为10克,容量为16GB,那么大约10,000吨RAM,这不是地球质量的一个特别值得注意的部分 - 你可以适应它,以及所需的计算基础设施,只需一个非常昂贵的数据中央. (4认同)

Gre*_*ill 5

不考虑内存,数组的最大大小受用于索引数组的整数类型的限制。