What is the maximum size of an array in C?

CArrays

C Problem Overview


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?

C Solutions


Solution 1 - C

There is no fixed limit to the size of an array in 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.)

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).

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.

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.

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.

Solution 2 - C

C99 5.2.4.1 "Translation limits" minimal size

> 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) > > - 65535 bytes in an object (in a hosted environment only) > > 13) Implementations should avoid imposing fixed translation limits whenever possible.

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

PTRDIFF_MAX also imposes some limits on array says

The C99 standard 6.5.6 Additive operators says:

> 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.

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.

So perhaps for this reason, GCC just seems to limit you to ptrdiff_t. This is also mentioned at: https://stackoverflow.com/questions/42574890/why-is-the-maximum-size-of-an-array-too-large-in-gcc/42575849#42575849

Experiments

Maybe what ultimately matters is whatever your compiler will accept, so here we go:

main.c

#include <stdint.h>

TYPE a[(NELEMS)];

int main(void) {
	return 0;
}

sizes.c

#include <stdint.h>
#include <stdio.h>

int main(void) {
    printf("PTRDIFF_MAX 0x%jx\n", (uintmax_t)PTRDIFF_MAX);
    printf("SIZE_MAX    0x%jx\n", (uintmax_t)SIZE_MAX);
    return 0;
}

And then we try to compile with:

gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o sizes.out sizes.c
./sizes.out
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out \
  -DNELEMS='((2lu << 62) - 1)' -DTYPE=uint8_t main.c 

Results:

  • PTRDIFF_MAX: 0x7fffffffffffffff = 2^63 - 1

  • SIZE_MAX: 0xffffffffffffffff = 2^64 - 1

  • -DNELEMS='((2lu << 62) - 1)' -DTYPE=uint8_t: compiles (== 2^63 - 1). Running it segfaults immediately on my mere 32 GB RAM system :-)

  • -DNELEMS='(2lu << 62)' -DTYPE=uint8_t: compilation fails with:

    error: size of array ‘a’ is too large
    
  • -DNELEMS='(2lu << 62 - 1)' -DTYPE=uint16_t: compilation fails with:

    error: size ‘18446744073709551614’ of array ‘a’ exceeds maximum object size ‘9223372036854775807

    where 9223372036854775807 == 0x7fffffffffffffff

So from this we understand that GCC imposes two limitations with different error messages:

  • number of elements cannot exceed 2^63 (happens to == PTRDIFF_MAX)
  • array size cannot exceed 2^63 (also happens to == PTRDIFF_MAX)

Tested on Ubuntu 20.04 amd64, GCC 9.3.0.

See also

Solution 3 - C

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

Solution 4 - C

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

Solution 5 - C

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)

Solution 6 - C

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.

Solution 7 - C

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.

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.

Hope that helps.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNyxmView Question on Stackoverflow
Solution 1 - CKeith ThompsonView Answer on Stackoverflow
Solution 2 - CCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 3 - CGreg HewgillView Answer on Stackoverflow
Solution 4 - CgregView Answer on Stackoverflow
Solution 5 - CJohn3136View Answer on Stackoverflow
Solution 6 - CFemarefView Answer on Stackoverflow
Solution 7 - CAntonioView Answer on Stackoverflow