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

时间:2022-11-12 21:31:24

I understand that hardware will limit the amount of memory allocated during program execution. However, my question is without regard to hardware. Assuming that there was no limit to the amount of memory, would there be no limit to the array?

我知道硬件将限制程序执行过程中分配的内存数量。然而,我的问题是关于硬件的。假设内存的数量没有限制,那么数组是否没有限制?

7 个解决方案

#1


36  

There is no fixed limit to the size of an array in C.

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

The size of any single object, including of any array object, is limited by SIZE_MAX, the maximum value of type size_t, which is the result of the sizeof operator. (It's not entirely clear whether the C standard permits objects larger than SIZE_MAX bytes, but in practice such objects are not supported; see footnote.) Since SIZE_MAX is determined by the implementation, and cannot be modified by any program, that imposes an upper bound of SIZE_MAX bytes for any single object. (That's an upper bound, not a least upper bound; implementations may, and typically do, impose smaller limits.)

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

The width of the type void*, a generic pointer type, imposes an upper bound on the total size of all objects in an executing program (which may be larger than the maximum size of a single object).

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

The C standard imposes lower bounds, but not upper bounds, on these fixed sizes. No conforming C implementation can support infinite-sized objects, but it can in principle support objects of any finite size. Upper bounds are imposed by individual C implementations, by the environments in which they operate, and by physics, not by the language.

C标准对这些固定大小施加下界,但不是上界。不一致的C实现可以支持无限大小的对象,但是它可以在原则上支持任何有限大小的对象。上界是由个别的C实现,由它们运作的环境和物理而不是语言强加的。

For example, a conforming implementation could have SIZE_MAX equal to 21024-1, which means it could in principle have objects up to 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 bytes.

例如,一个符合标准的实现可以有SIZE_MAX = 21024-1,这意味着它可以在理论上有一些对象,可以达到179769313486231590772930617976978978973267326758055009732240732240732240732240723971371387137239713723971241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241282399315823993158239971608239971608239971608239971608239971608239971608239971608239971608239971639971630823997160823997160823997160823997160823997163997160823997160823997163997160823997163997160497163997

Good luck finding hardware that actually supports such objects.

祝您好运,找到真正支持这些对象的硬件。

Footnote: There is no explicit rule that no object can be bigger than SIZE_MAX bytes. You couldn't usefully apply the sizeof operator to such an object, but like any other operator, sizeof can overflow; that doesn't mean you couldn't perform operations on such an object. But in practice, any sane implementation will make size_t big enough to represent the size of any object it supports.

脚注:没有明确规定任何对象都不能大于SIZE_MAX字节。您无法有效地将sizeof运算符应用到这样的对象上,但是与任何其他运算符一样,sizeof可以溢出;这并不意味着不能对这样的对象执行操作。但是在实践中,任何健全的实现都会使size_t足够大来表示它支持的任何对象的大小。

#2


7  

C99 5.2.4.1 "Translation limits" minimal size

c995.2.4.1“翻译限制”最小尺寸。

The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits: 13)

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

  • 65535 bytes in an object (in a hosted environment only)
  • 对象中的65535字节(仅在托管环境中)

13) Implementations should avoid imposing fixed translation limits whenever possible.

13)实现应该尽量避免强加固定的翻译限制。

This suggests that a conforming implementation could refuse to compile an object (which includes arrays) with more than short bytes.

这表明,符合条件的实现可以拒绝编译一个大于短字节的对象(包括数组)。

PTRDIFF_MAX seems to be a practical limit for static array objects

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

The C99 standard 6.5.6 Additive operators says:

C99标准6.5.6加性运营商表示:

9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. If the result is not representable in an object of that type, the behavior is undefined.

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

Which implies to me that arrays larger than ptrdiff_t are allowed in theory, but then you cannot take the difference of their addresses portabibly.

这对我来说意味着大于ptrdiff_t的数组在理论上是允许的,但是你不能以可移植性的方式计算它们的地址差。

So perhaps for this reason, GCC just seems to limit you to ptrdiff_t. This is also mentioned at: Why is the maximum size of an array "too large"?

因此,也许正因为这个原因,GCC只是把你限制在ptrdiff_t。在:为什么数组的最大大小“太大”?

I have empirically verified this with main.c:

我已经通过经验证明了这一点。

#include <stdint.h>

uint8_t a[(X)];

int main(void) {
    return 0;
}

and then in Ubunbu 17.10:

然后在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
$

See also

另请参阅

#3


6  

A 64-bit machine could theoretically address a maximum of 2^64 bytes of memory.

64位机理论上可以解决最多2 ^ 64字节的内存。

#4


4  

Without regard for memory, the maximum size of an array is limited by the type of integer used to index the array.

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

#5


2  

I guess the biggest theoretical array would be the max value of "unsigned long" (or whatever the biggest integer number the latest standard / your compiler supports)

我猜最大的理论数组应该是“无符号长”的最大值(或者任何最新标准/编译器支持的最大整数)

#6


2  

The size of the pointer will limit the memory you are able to access. Even if the hardware offers support for unlimited memory, if the largest datatype you are able to use is 64 bit, you'll only be able to access 2^64 bytes of memory.

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

#7


0  

I was looking for a way to determine the maximum size for an array. This question seems to ask the same, so I want to share my findings.

我正在寻找一种方法来确定数组的最大大小。这个问题似乎也有同样的问题,所以我想分享我的发现。

Initially, C does not provide any function to determine the maximum number of elements allocable in an array in compilation time. This is because it will depend of the memory of available in the machine where it will be executed.

最初,C不提供任何函数来确定在编译时数组中可分配的元素的最大数量。这是因为它将依赖于要执行它的机器中的可用内存。

On the other hand, I have found, that memory allocation functions (calloc() and malloc()) enable to allocate larger arrays. Moreover, these functions allows you to handle runtime memory allocation errors.

另一方面,我发现内存分配函数(calloc()和malloc())能够分配更大的数组。此外,这些函数允许您处理运行时内存分配错误。

Hope that helps.

希望有帮助。

#1


36  

There is no fixed limit to the size of an array in C.

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

The size of any single object, including of any array object, is limited by SIZE_MAX, the maximum value of type size_t, which is the result of the sizeof operator. (It's not entirely clear whether the C standard permits objects larger than SIZE_MAX bytes, but in practice such objects are not supported; see footnote.) Since SIZE_MAX is determined by the implementation, and cannot be modified by any program, that imposes an upper bound of SIZE_MAX bytes for any single object. (That's an upper bound, not a least upper bound; implementations may, and typically do, impose smaller limits.)

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

The width of the type void*, a generic pointer type, imposes an upper bound on the total size of all objects in an executing program (which may be larger than the maximum size of a single object).

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

The C standard imposes lower bounds, but not upper bounds, on these fixed sizes. No conforming C implementation can support infinite-sized objects, but it can in principle support objects of any finite size. Upper bounds are imposed by individual C implementations, by the environments in which they operate, and by physics, not by the language.

C标准对这些固定大小施加下界,但不是上界。不一致的C实现可以支持无限大小的对象,但是它可以在原则上支持任何有限大小的对象。上界是由个别的C实现,由它们运作的环境和物理而不是语言强加的。

For example, a conforming implementation could have SIZE_MAX equal to 21024-1, which means it could in principle have objects up to 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 bytes.

例如,一个符合标准的实现可以有SIZE_MAX = 21024-1,这意味着它可以在理论上有一些对象,可以达到179769313486231590772930617976978978973267326758055009732240732240732240732240723971371387137239713723971241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241241282399315823993158239971608239971608239971608239971608239971608239971608239971608239971608239971639971630823997160823997160823997160823997160823997163997160823997160823997163997160823997163997160497163997

Good luck finding hardware that actually supports such objects.

祝您好运,找到真正支持这些对象的硬件。

Footnote: There is no explicit rule that no object can be bigger than SIZE_MAX bytes. You couldn't usefully apply the sizeof operator to such an object, but like any other operator, sizeof can overflow; that doesn't mean you couldn't perform operations on such an object. But in practice, any sane implementation will make size_t big enough to represent the size of any object it supports.

脚注:没有明确规定任何对象都不能大于SIZE_MAX字节。您无法有效地将sizeof运算符应用到这样的对象上,但是与任何其他运算符一样,sizeof可以溢出;这并不意味着不能对这样的对象执行操作。但是在实践中,任何健全的实现都会使size_t足够大来表示它支持的任何对象的大小。

#2


7  

C99 5.2.4.1 "Translation limits" minimal size

c995.2.4.1“翻译限制”最小尺寸。

The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits: 13)

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

  • 65535 bytes in an object (in a hosted environment only)
  • 对象中的65535字节(仅在托管环境中)

13) Implementations should avoid imposing fixed translation limits whenever possible.

13)实现应该尽量避免强加固定的翻译限制。

This suggests that a conforming implementation could refuse to compile an object (which includes arrays) with more than short bytes.

这表明,符合条件的实现可以拒绝编译一个大于短字节的对象(包括数组)。

PTRDIFF_MAX seems to be a practical limit for static array objects

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

The C99 standard 6.5.6 Additive operators says:

C99标准6.5.6加性运营商表示:

9 When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. If the result is not representable in an object of that type, the behavior is undefined.

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

Which implies to me that arrays larger than ptrdiff_t are allowed in theory, but then you cannot take the difference of their addresses portabibly.

这对我来说意味着大于ptrdiff_t的数组在理论上是允许的,但是你不能以可移植性的方式计算它们的地址差。

So perhaps for this reason, GCC just seems to limit you to ptrdiff_t. This is also mentioned at: Why is the maximum size of an array "too large"?

因此,也许正因为这个原因,GCC只是把你限制在ptrdiff_t。在:为什么数组的最大大小“太大”?

I have empirically verified this with main.c:

我已经通过经验证明了这一点。

#include <stdint.h>

uint8_t a[(X)];

int main(void) {
    return 0;
}

and then in Ubunbu 17.10:

然后在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
$

See also

另请参阅

#3


6  

A 64-bit machine could theoretically address a maximum of 2^64 bytes of memory.

64位机理论上可以解决最多2 ^ 64字节的内存。

#4


4  

Without regard for memory, the maximum size of an array is limited by the type of integer used to index the array.

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

#5


2  

I guess the biggest theoretical array would be the max value of "unsigned long" (or whatever the biggest integer number the latest standard / your compiler supports)

我猜最大的理论数组应该是“无符号长”的最大值(或者任何最新标准/编译器支持的最大整数)

#6


2  

The size of the pointer will limit the memory you are able to access. Even if the hardware offers support for unlimited memory, if the largest datatype you are able to use is 64 bit, you'll only be able to access 2^64 bytes of memory.

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

#7


0  

I was looking for a way to determine the maximum size for an array. This question seems to ask the same, so I want to share my findings.

我正在寻找一种方法来确定数组的最大大小。这个问题似乎也有同样的问题,所以我想分享我的发现。

Initially, C does not provide any function to determine the maximum number of elements allocable in an array in compilation time. This is because it will depend of the memory of available in the machine where it will be executed.

最初,C不提供任何函数来确定在编译时数组中可分配的元素的最大数量。这是因为它将依赖于要执行它的机器中的可用内存。

On the other hand, I have found, that memory allocation functions (calloc() and malloc()) enable to allocate larger arrays. Moreover, these functions allows you to handle runtime memory allocation errors.

另一方面,我发现内存分配函数(calloc()和malloc())能够分配更大的数组。此外,这些函数允许您处理运行时内存分配错误。

Hope that helps.

希望有帮助。