programing

C에서 배열의 최대 크기는?

prostudy 2022. 4. 18. 21:13
반응형

C에서 배열의 최대 크기는?

나는 하드웨어가 프로그램 실행 중에 할당된 메모리 양을 제한할 것이라고 알고 있다.그러나 나의 질문은 하드웨어와 무관하다.메모리 양에 제한이 없다고 가정하면 어레이에 제한이 없을까?

C에서 배열의 크기에 대한 고정된 제한은 없다.

어레이 개체를 포함한 단일 개체의 크기는 다음과 같이 제한됨SIZE_MAX , 타입의 최대대.size_t, 어느 것이 의 결과인가.sizeof교환원의(C 표준이 다음보다 큰 물체를 허용하는지 여부는 완전히 명확하지 않다.SIZE_MAX바이트, 그러나 실제로는 이러한 개체가 지원되지 않는다. 각주를 참조하십시오.)이후SIZE_MAX상한을 부과하는 어떤 프로그램으로도 수정할 수 없는 구현에 의해 결정된다.SIZE_MAX단日바that ((이것은 상한이 아니며 최소 상한이 아니며, 일반적으로 구현은 더 작은 제한을 가할 수 있다.)

의 폭.void*일반 포인터 유형은 실행 프로그램에 있는 모든 개체의 전체 크기에 상한을 부과한다(단일 개체의 최대 크기보다 클 수 있음).

C 표준은 이러한 고정된 크기에 대해 하한을 부과하지만 상한은 부과하지 않는다.적합한 C 구현은 무한대의 개체를 지원할 수 없지만, 원칙적으로 유한한 크기의 개체를 지원할 수 있다.상한은 개별 C 구현, C 구현이 작동하는 환경, 그리고 언어가 아닌 물리학에 의해 부과된다.

를 들어,은 have예 어어, 적한 could을 가질 수 있다.SIZE_MAX21024-1하는 것이 원칙적으로 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938까지 개체 할 수 있음을 의미한 동일.4797163048356329624224137215바이트.

이러한 개체를 실제로 지원하는 하드웨어를 찾으십시오.

각주:어떤 물체도 다음보다 클 수 없다는 명시적인 규칙은 없다.SIZE_MAX 당신은 이 수 없었다. 당신은 유용하게 적용할 수 없었다.sizeof 다다이 운영자이나 마마마나로,sizeof넘칠 수 있다; 그것은 당신이 그런 물체에 대해 작업을 수행할 수 없다는 것을 의미하지 않는다.하지만 실제로, 모든 제정신 구현은size_t그것이 지원하는 어떤 물체의 크기를 나타낼 수 있을 만큼 충분히 크다.

C99 5.2.4.1 "번역 한계" 최소 크기

실행은 다음 제한사항 중 하나 이상의 인스턴스를 포함하는 하나 이상의 프로그램을 번역하고 실행할 수 있어야 한다. 13)

  • 개체의 65535바이트(호스트 환경에만 해당)
  1. 구현 시 가능한 경우 고정된 번역 제한을 적용하지 않아야 한다.

이는 준수한 구현이 다음을 초과하는 객체(배열을 포함)의 컴파일을 거부할 수 있음을 시사한다.short바이트 수

PTRDIFF_MAX또한 어레이에 약간의 제한을 가한다.

C99 표준 6.5.6 적층 연산자는 다음과 같이 말한다.

9 두 포인터를 빼면, 두 포인터가 모두 동일한 배열 객체의 요소 또는 배열 객체의 마지막 요소를 가리킨다. 그 결과는 두 배열 요소의 첨자 차이를 나타낸다.그은 결의 크의 크는형(서명정수형)이다.ptrdiff_t에 규정된.<stddef.h>머리글를 나타낼 수 되지 않는다결과가 해당 유형의 개체에서 나타낼 수 없는 경우 동작은 정의되지 않는다.

, 큰 은 즉, 보다보다 큰 배열임을 알수 있다.ptrdiff_t이론상으로는 허용되지만, 그러면 당신은 그들의 주소의 차이를 눈에 띄게 받아들일 수 없다.

그래서 아마 이런 이유 때문에 GCC는 단지 당신을ptrdiff_t. 이 내용은 다음에서도 언급된다.배열의 최대 크기가 "너무 큰" 이유

실험

아마도 궁극적으로 중요한 것은 컴파일러가 받아들일 것이 무엇이든지일 것이다. 그래서 우리는 이렇게 한다.

본시

#include <stdint.h>

TYPE a[(NELEMS)];

int main(void) {
    return 0;
}

size.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;
}

그리고 다음과 같이 컴파일하려고 한다.

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 

결과:

  • PTRDIFF_MAX: 0x7ffffffffffffff = 2^63 - 1

  • SIZE_MAX: 0xffffffffffffffff = 2^64 - 1

  • -DNELEMS='((2lu << 62) - 1)' -DTYPE=uint8_t:例句】(= 2^63 - 1) 32GB RAM 【시(時)】【시(時)】

  • -DNELEMS='(2lu << 62)' -DTYPE=uint8_t: 컴파일이 실패하고 다음이 발생함:

    error: size of array ‘a’ is too large
    
  • -DNELEMS='(2lu << 62 - 1)' -DTYPE=uint16_t: 컴파일이 실패하고 다음이 발생함:

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

    어디에9223372036854775807 == 0x7fffffffffffffff

따라서 이를 통해 우리는 GCC가 서로 다른 오류 메시지와 함께 두 가지 제한을 부과한다는 것을 이해한다.

  • 요소 수는 2^63을 초과할 수 없음(=PTRDIFF_MAX에 해당하는 경우)
  • 어레이 크기는 2^63을 초과할 수 없음( == PTRDIFF_MAX에도 해당됨)

Ubuntu 20.04 amd64, GCC 9.3.0에서 시험.

참고 항목

가장 큰 이론 배열은 "부호화되지 않은 긴 길이"의 최대 값(또는 가장 큰 정수 번호에 상관없이 최신 표준 / 컴파일러 지원)일 것이다.

메모리를 고려하지 않고 배열의 최대 크기는 배열 인덱스에 사용되는 정수 유형에 의해 제한된다.

64비트 기계는 이론적으로 최대 2^64바이트의 메모리를 처리할 수 있다.

포인터의 크기는 당신이 접근할 수 있는 메모리를 제한할 것이다.하드웨어가 무제한 메모리를 지원한다고 해도 사용할 수 있는 최대 데이터 유형이 64비트라면 2^64바이트의 메모리만 액세스할 수 있다.

배열의 최대 크기를 결정하는 방법을 찾고 있었다.이 질문도 마찬가지인 것 같으니, 내 연구 결과를 공유하고 싶다.

처음에 C는 배열에서 컴파일 시간에 할당할 수 있는 요소의 최대 수를 결정하는 기능을 제공하지 않는다.실행될 기계에서 사용할 수 있는 메모리에 따라 달라지기 때문이다.

한편, 나는 메모리 할당 기능(memory allocation function)을 발견했다.calloc()그리고malloc()더 큰 할 수 더 큰 배열을 할당할 수 있음.게다가, 이러한 기능들은 당신이 런타임 메모리 할당 오류를 처리할 수 있게 해준다.

그게 도움이 되길 바래.

참조URL: https://stackoverflow.com/questions/9386979/what-is-the-maximum-size-of-an-array-in-c

반응형