C ++에 최대 배열 길이 제한이 있습니까?


183

C ++에서 배열의 최대 길이가 있습니까?

그것은 C ++ 제한입니까, 아니면 내 컴퓨터에 의존합니까? 조정할 수 있습니까? 배열의 유형에 따라 달라 집니까?

어떻게 든 그 한계를 깨뜨릴 수 있습니까? 아니면 정보를 저장하는 더 좋은 방법을 찾아야합니까? 그리고 가장 간단한 방법은 무엇입니까?

내가해야 할 일은 배열에 long int를 저장하는 것입니다 .Linux 환경에서 일하고 있습니다. 내 질문은 : N> 10 자리수의 N long long 정수 배열을 저장 해야하는 경우 어떻게해야합니까?

학교를 위해 암호화 알고리즘 (예 : p-Pollard와 같은)을 작성하고 있기 때문에 정수가 필요합니다.

답변:


163

C ++가 아니라 하드웨어에 의해 적용되는 두 가지 제한이 있습니다.

첫 번째 한계 (도달해서는 안 됨)는 배열의 인덱스를 설명하는 데 사용되는 크기 유형 (및 크기)의 제한에 의해 설정됩니다. 시스템이 std::size_t취할 수 있는 최대 값으로 제공됩니다 . 이 데이터 유형은 객체의 크기를 바이트 단위로 포함하기에 충분히 큽니다.

다른 한계는 실제 메모리 한계입니다. 배열의 객체가 클수록 메모리가 가득 차서이 제한에 더 빨리 도달합니다. 예를 들어, vector<int>주어진 크기 n 의 a 는 일반적으로보다 큼 vector<char>때문에 유형의 배열 (작은 상수 값 빼기) 보다 몇 배나 많은 메모리를 필요로합니다 . 따라서 a 에는 이전 메모리가 가득 찼을 때보 다 많은 항목이 포함될 수 있습니다 . 원시 C 스타일 배열 같은 수는 좋아 하고 .intcharvector<char>vector<int>int[]char[]

또한이 상한 은 원하는 방식으로 메모리를 자유롭게 관리 할 수 있기 때문에 allocator구성하는 데 사용되는 유형에 따라 영향을받을 수 있습니다 . 매우 이상하지만 생각할 수없는 할당자는 객체의 동일한 인스턴스가 리소스를 공유하는 방식으로 메모리를 풀링 할 수 있습니다. 이렇게하면 사용 가능한 모든 메모리를 모두 사용하는 컨테이너에 동일한 객체를 많이 삽입 할 수 있습니다.vectorallocator

그 외에도 C ++은 제한을 두지 않습니다.


20
또한 구현에 따라 다르지만 변경할 수있는 스레드를 사용하는 경우 일반적으로 스택 크기 제한에 쉽게 도달 할 수 있습니다.
Alaric

@Alaric : 맞습니다. 시스템 사양이 너무 다르고 전문가가 아니기 때문에 시스템 사양에 너무 깊이 들어가고 싶지 않았습니다.
Konrad Rudolph

@Konrad, 할당 자 유형에 관한 흥미로운 점. 정보 주셔서 감사합니다.
SmacL

11
std :: size_t는 일반적으로 포인터의 크기이며 정수 수학 단위에서 기본 하드웨어를 지원하는 가장 큰 정수의 크기가 아닙니다. 내가 사용한 모든 x86 OS에서 size_t는 32 비트 OS의 경우 32 비트이고 64 비트 OS의 경우 64 비트입니다.
Mr Fooz

2
내 이해는 배열 의 최대 한계가 프로세서 단어 의 최대 값 이라는 것 입니다. 이것은 인덱싱 연산자 때문입니다. 예를 들어, 머신은 워드 크기가 16 비트이지만 어드레싱 레지스터는 32 비트 일 수 있습니다. 메모리 청크는 new또는에 전달 된 매개 변수에 의해 크기가 제한됩니다 malloc. 배열보다 큰 메모리 청크는 포인터를 통해 액세스 할 수 있습니다.
Thomas Matthews

171

아무도 스택 프레임 의 크기에 대한 제한을 언급하지 않았습니다 .

메모리를 할당 할 수있는 두 곳이 있습니다.

  • 힙에서 (동적으로 할당 된 메모리)
    여기에서 크기 제한은 사용 가능한 하드웨어와 다른 장치를 사용하여 사용하지 않는 데이터를 임시로 저장 ( 즉, 페이지를 하드 디스크로 이동) 하여 공간을 시뮬레이션하는 OS 기능의 조합입니다 .
  • 스택에서 (로컬로 선언 된 변수).
    여기서 크기 제한은 가능한 하드웨어 제한과 함께 컴파일러 정의입니다. 컴파일러 문서를 읽으면 종종이 크기를 조정할 수 있습니다.

따라서 배열을 동적으로 할당하는 경우 (한도가 커서 다른 게시물에 의해 자세히 설명됩니다.

int* a1 = new int[SIZE];  // SIZE limited only by OS/Hardware

또는 배열이 스택에 할당 된 경우 스택 프레임의 크기에 의해 제한됩니다. NB 벡터 및 기타 컨테이너는 스택에 존재하지 않지만 일반적으로 대량의 데이터가 힙에 있습니다.

int a2[SIZE]; // SIZE limited by COMPILER to the size of the stack frame

4
큰 배열의 바람직한 할당은 스택에 없거나 전체적으로 정의 아니라 동적 할당을 통해 (비아 new또는 malloc).
Thomas Matthews

1
@ 토마스 매튜 : 내 세상에 없습니다. 동적으로 할당 된 객체는 관리가 필요합니다. 동적으로 할당 해야하는 경우 std :: vector와 같이 동적으로 할당 된 메모리를 나타내는 스택 객체를 사용합니다.
Martin York

2
가없는 한 cornor 경우는 다음과 같습니다 Global Arrays되지 않은 아름다움과 가장 피해야가, 이들의 제한에 해당되지 않는 반면, stack필요하지 않은 malloc/ free그들과 함께 일을.
ted

1
@ted, 왜 전역 배열을 "가장 잘 피해야"하는가? 더 정확하게 말하면 정적으로 할당 된 배열을 의미한다고 생각합니다. 그들의 범위가 글로벌 일 필요는 없습니다. 동적으로 할당 된 배열로는 할 수없는 절대 주소 지정 (적어도 Linux에서는)을 사용할 수 있기 때문에 동적 배열보다 낫다고 주장합니다.
Z boson

2
매우 중요한 점. 최근에 구성 가능한 최대 버퍼 크기를 제공하는 "생산 품질"오픈 소스 프로젝트를 발견했습니다. 모든 버퍼가 스택에 할당되었으므로 충분히 큰 값을 구성하면 시작시 프로그램이 즉시 segfault가됩니다.
aroth

13

32 비트 Windows 시스템에서 이론적 인 관점이 아니라 실용적인 관점에서 보면 단일 프로세스에 사용 가능한 최대 총 메모리 양은 2GB입니다. 훨씬 더 많은 실제 메모리가있는 64 비트 운영 체제로 이동하면 한계를 극복 할 수 있지만이를 수행할지 아니면 대안을 찾을 지 여부는 의도 한 사용자와 예산에 따라 크게 달라집니다. PAE를 사용하여 다소 확장 할 수도 있습니다 .

많은 컴파일러에서 기본 구조 정렬이 8 바이트이므로 배열의 유형은 매우 중요합니다. 이는 메모리 사용에 문제가있는 경우 매우 낭비입니다. Visual C ++를 사용하여 Windows를 대상 으로하는 경우이를 극복하는 방법으로 #pragma pack 지시문을 확인하십시오 .

또 다른 방법은 희소 행렬, 즉석 압축 등 메모리 압축 기술에서 어떤 점이 도움이 될 수 있는지 살펴 보는 것입니다. 다시 말하지만 이는 응용 프로그램에 따라 크게 달라집니다. 실제로 배열에 무엇이 있는지에 대한 정보를 더 제공하기 위해 게시물을 편집하면 더 유용한 답변을 얻을 수 있습니다.

편집 : 정확한 요구 사항에 대한 자세한 정보가 제공되면 스토리지는 압축되지 않은 7.6GB와 76GB 사이 인 것으로 보이며 C ++의 메모리에 배열로 저장하려면 다소 비싼 64 비트 상자가 필요합니다. 액세스 속도를 고려하고 임의 액세스를 허용하는 메모리에 데이터를 저장하려는 이유는 무엇입니까? 이 데이터를 배열 외부에 저장하는 가장 좋은 방법은 액세스 방법에 따라 다릅니다. 배열 구성원에 무작위로 액세스해야하는 경우 대부분의 응용 프로그램에서 동시에 액세스되는 경향이있는 데이터 덩어리를 그룹화하는 방법이 있습니다. 예를 들어, 대규모 GIS 및 공간 데이터베이스에서 데이터는 종종 지리적 영역별로 타일링됩니다. C ++ 프로그래밍 용어에서는 필요에 따라 [] 배열 연산자를 재정 의하여 외부 저장소에서 데이터의 일부를 가져올 수 있습니다.


1
프로그램 공간 외부에 메모리를 할당 할 수있는 시스템 호출이 있습니다. 그러나 이것은 OS에 따라 다르며 이식성이 없습니다. 우리는 그것들을 임베디드 시스템에서 사용했습니다.
Thomas Matthews

4

위의 내용에 동의합니다. 배열을 초기화하는 경우

 int myArray[SIZE] 

그런 다음 SIZE는 정수 크기에 의해 제한됩니다. 그러나 malloc이 NULL을 반환하지 않는 한 원하는만큼 큰 메모리 청크를 malloc하고 그에 대한 포인터를 가질 수 있습니다.


이것이 잘못되었는지, 아니면 당신이나 다른 것을 오해했는지 잘 모르겠습니다. 예를 들어, 이것은 MSVC17 컴파일러에 의해 방지된다 : int oops[INT_MAX]{0};그것은 생성C2148 - total size of array must not exceed 0x7fffffff bytes
kayleeFrye_onDeck

66%VS2017을 사용하여 Windows 10에서 디버그로 앱을 시작하기 전에 16GB DDR4와 현재 사용되는 메모리를 사용하여 초기화 할 수있는 int-array의 크기에 대한 정의가 제한되어 있습니다 0. 때로는 ~ 257k 요소로 할 수 있으며 때로는 스택 오버플로가 발생합니다. 메인 및 배열 외에 내 앱 에 아무것도 추가하면 해당 숫자가 (분명히) 내려갑니다. 이 숫자를 결정하기 위해 실험해야했기 때문에이 메트릭이 진공에서 이론적 한계를 아는 것 이상으로 어떻게 신뢰할 수 있는지 알 수 없습니다.
kayleeFrye_onDeck

4

응답을 요약하고, 확장하고, 질문에 직접 대답하기 위해 :

C ++은 배열 의 차원 에 제한을 두지 않습니다 .

그러나 어레이를 메모리 어딘가에 저장해야하므로 컴퓨터 시스템의 다른 부분에 의해 부과 된 메모리 관련 제한이 적용됩니다. 이러한 제한에 직접 관련되지 않는다는 것을주의 차원 배열 (= 요소의 수)가 아니라 그것으로 크기 (= 메모리의 양이 촬영). 치수 ( D ) 및 메모리 크기 ( S 들이 단일 요소 (촬영하여 메모리에 관련된으로 배열)이 동일하지 않은 E ) S = D * E .

지금E 는 다음에 의존합니다.

  • 배열 요소의 유형 (요소는 더 작거나 더 클 수 있음)
  • 메모리 정렬 (성능을 높이기 위해 요소는 일부 값의 배수 인 주소에 배치되며
    요소 사이에 '공간 낭비'(패딩)이 발생 함)
  • 객체의 정적 부분의 크기 (객체 지향 프로그래밍에서 동일한 유형의 객체의 정적 구성 요소는 동일한 유형의 객체 수에 관계없이 한 번만 저장 됨)

: 또한 주 일반적 (자동 변수로 스택에 배열 된 데이터를 할당하여 서로 다른 메모리 관련 제한을 얻을 int t[N]또는 힙 (와 동적 alocation) malloc()/ new(AS 또는 STL 메커니즘을 이용하여), 또는 프로세스 메모리의 정적 부분 정적 변수 :) static int t[N]. 힙에 할당 할 때에도 힙 할당 메모리 블록에 대한 참조를 저장하려면 스택에 약간의 메모리가 필요합니다 (그러나 일반적으로 무시할 수 있습니다). 컴파일러의 프로 바이더는 주어진 플랫폼에서 가능한 최대 메모리 양을 처리 할 수있을 정도로 큰 정수 타입 이어야 하므로 타입

의 크기는 size_t프로그래머에게 영향을 미치지 않습니다 (프로그래머가 size_t의도 한대로 인덱싱에 타입을 사용한다고 가정 ) typedef건축물.

메모리 크기 제한의 원인은 다음과 같습니다.

  • 프로세스에 사용 가능한 메모리 양 (64 비트 OS 커널에서도 32 비트 응용 프로그램의 경우 2 ^ 32 바이트로 제한됨)
  • 프로세스 메모리의 분할 (예 : 스택 또는 힙을 위해 설계된 프로세스 메모리의 양)
  • 물리 메모리의 조각화
  • 실제 메모리 양
  • 그리고 가상 메모리의 양.

응용 프로그램 수준에서 '조정'할 수는 없지만 다른 컴파일러를 사용하거나 (스택 크기 제한을 변경하기 위해) 응용 프로그램을 64 비트로 이식하거나 다른 OS로 이식하거나 물리적 / (가상? 실제?) 머신의 가상 메모리 구성.

위의 모든 요소를 ​​외부 장애로 인해 런타임 오류의 원인으로 취급하고 프로그램 코드에서 메모리 할당 관련 오류를주의 깊게 확인 및 대응하는 것은 드문 일이 아니며 권장되지도 않습니다.

그래서 마지막으로 : C ++은 어떤 제한도 부과하지 않지만 코드를 실행할 때 여전히 메모리와 관련된 불리한 조건을 확인해야합니다 ... :-)


3

많은 훌륭한 답변이 언급했듯이 C ++ 컴파일러 버전, 운영 체제 및 컴퓨터 특성에 따라 많은 제한이 있습니다. 그러나 파이썬에서 컴퓨터의 한계를 확인하는 다음 스크립트를 제안합니다.

이진 검색을 사용하고 각 반복에서 크기의 배열을 작성하는 코드를 작성하여 중간 크기가 가능한지 확인합니다. 스크립트는이를 컴파일 (미안하지만이 부분은 Linux에서만 작동 함)하고 성공에 따라 이진 검색을 조정하려고합니다. 확인 해봐:

import os

cpp_source = 'int a[{}]; int main() {{ return 0; }}'

def check_if_array_size_compiles(size):
        #  Write to file 1.cpp
        f = open(name='1.cpp', mode='w')
        f.write(cpp_source.format(m))
        f.close()
        #  Attempt to compile
        os.system('g++ 1.cpp 2> errors')
        #  Read the errors files
        errors = open('errors', 'r').read()
        #  Return if there is no errors
        return len(errors) == 0

#  Make a binary search. Try to create array with size m and
#  adjust the r and l border depending on wheather we succeeded
#  or not
l = 0
r = 10 ** 50
while r - l > 1:
        m = (r + l) // 2
        if check_if_array_size_compiles(m):
                l = m
        else:
                r = m

answer = l + check_if_array_size_compiles(r)
print '{} is the maximum avaliable length'.format(answer)

컴퓨터에 저장 한 다음 실행할 수 있으며 생성 할 수있는 최대 크기를 인쇄합니다. 내 컴퓨터의 경우 2305843009213693951입니다.


2

내가 생각하지 않은 한 가지는 이전 답변에서 언급되었습니다.

나는 사람들이 디자인에 그런 것들을 사용할 때 리팩토링 의미에서 항상 "나쁜 냄새"를 감지하고 있습니다.

이는 효율성 측면과 성능 관점 모두에서 데이터를 표현하는 가장 좋은 방법은 아니며 거대한 배열입니다.

건배,


내가 사용해야 할 것에 대한 제안이 있습니까?
luiss

저장하는 데이터가 무엇인지 알려 주면 가능할 수 있습니다. (-:
Rob Wells

미안 루이스 내 첫 응답은 매우 플립 패트했다. 데이터의 특성에 따라 결정됩니다. 데이터의 관계는 데이터를 나타내는 데 사용하는 모델을 주도합니다. 그런 다음 컬렉션 그 점에서 분명 해야 합니다. 그렇지 않다면 데이터 모델에 대해 걱정할 것입니다.
Rob Wells

나에게 그렇게 flippant : 이런 장난감이있는 캐시 된 데이터베이스는 어떻습니까? tweaktown.com/news/22066/…

2

큰 데이터를 처리해야하는 경우이를 관리 가능한 청크로 분할해야합니다. 모든 소형 컴퓨터의 메모리에 모두 적합하지는 않습니다. 디스크에서 데이터의 일부 (적절하게 맞는 것)를로드하고 계산 및 변경을 수행하고 디스크에 저장 한 다음 완료 될 때까지 반복 할 수 있습니다.


메모리에 맞추기에는 너무 큰 데이터를 처리하기 위해 예제 알고리즘에서 병합 정렬을 참조하십시오.
Thomas Matthews

2

모든 현재 답변만큼 성가 시게 비특이적 인 답변은 대부분 옳지 만 항상 언급되지는 않지만 많은주의 사항이 있습니다. 요점은 두 개의 상한이 있으며 그중 하나만 실제로 정의 된 것이므로 YMMV :

1. 컴파일 시간 제한

기본적으로 컴파일러가 허용하는 것. x64 Windows 10 상자의 Visual C ++ 2017의 경우 2GB 제한이 발생하기 전 컴파일 타임의 최대 제한입니다.

unsigned __int64 max_ints[255999996]{0};

대신이 작업을 수행하면

unsigned __int64 max_ints[255999997]{0};

나는 얻을 것이다 :

Error C1126 automatic allocation exceeds 2G

2G가 255999996/에 어떻게 연관되어 있는지 잘 모르겠습니다 7. 두 숫자를 모두 봤는데 관련이있을 수있는 유일한 것은와 관련된 정밀도 문제dc 에 대한 * nix Q & A 였습니다. 어느 쪽이든, 어떤 유형의 int 배열을 채우려 고하는지, 얼마나 많은 요소를 할당 할 수 있는지는 중요하지 않습니다.

2. 런타임 제한

스택과 힙에는 고유 한 제한이 있습니다. 이러한 제한은 사용 가능한 시스템 리소스와 앱 자체의 "무거운"정도에 따라 달라지는 값입니다. 예를 들어 현재 시스템 리소스를 사용하면 다음을 실행할 수 있습니다.

int main()
{
    int max_ints[257400]{ 0 };
    return 0;
}

하지만 조금만 조정하면 ...

int main()
{
    int max_ints[257500]{ 0 };
    return 0;
}

밤! 스택 오버플로!

Exception thrown at 0x00007FF7DC6B1B38 in memchk.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000AA8DE03000). Unhandled exception at 0x00007FF7DC6B1B38 in memchk.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000AA8DE03000).

그리고 앱 포인트의 전체 무거움을 자세하게 설명하면 다음과 같습니다.

int main()
{
    int maxish_ints[257000]{ 0 };
    int more_ints[400]{ 0 };
    return 0;
}  

그러나 이로 인해 스택 오버플로가 발생했습니다.

int main()
{
    int maxish_ints[257000]{ 0 };
    int more_ints[500]{ 0 };
    return 0;
}  

1

std :: vectormax_size () 멤버 함수가 여기에 언급되지 않은 것에 놀랐습니다 .

"시스템 또는 라이브러리 구현 제한으로 인해 컨테이너가 보유 할 수있는 최대 요소 수를 리턴합니다 (예 : 가장 큰 컨테이너의 경우 std :: distance (begin (), end ()))."

우리는 그것이 std::vector후드 아래에 동적 배열로 구현되어 있다는 것을 알고 있으므로 컴퓨터 max_size()에서 동적 배열 의 최대 길이에 거의 근접 해야합니다.

다음 프로그램은 다양한 데이터 유형에 대한 대략적인 최대 배열 길이의 테이블을 작성합니다.

#include <iostream>
#include <vector>
#include <string>
#include <limits>

template <typename T>
std::string mx(T e) {
    std::vector<T> v;
    return std::to_string(v.max_size());
}

std::size_t maxColWidth(std::vector<std::string> v) {
    std::size_t maxWidth = 0;

    for (const auto &s: v)
        if (s.length() > maxWidth)
            maxWidth = s.length();

    // Add 2 for space on each side
    return maxWidth + 2;
}

constexpr long double maxStdSize_t = std::numeric_limits<std::size_t>::max();

// cs stands for compared to std::size_t
template <typename T>
std::string cs(T e) {
    std::vector<T> v;
    long double maxSize = v.max_size();
    long double quotient = maxStdSize_t / maxSize;
    return std::to_string(quotient);
}

int main() {
    bool v0 = 0;
    char v1 = 0;

    int8_t v2 = 0;
    int16_t v3 = 0;
    int32_t v4 = 0;
    int64_t v5 = 0;

    uint8_t v6 = 0;
    uint16_t v7 = 0;
    uint32_t v8 = 0;
    uint64_t v9 = 0;

    std::size_t v10 = 0;
    double v11 = 0;
    long double v12 = 0;

    std::vector<std::string> types = {"data types", "bool", "char", "int8_t", "int16_t",
                                      "int32_t", "int64_t", "uint8_t", "uint16_t",
                                      "uint32_t", "uint64_t", "size_t", "double",
                                      "long double"};

    std::vector<std::string> sizes = {"approx max array length", mx(v0), mx(v1), mx(v2),
                                      mx(v3), mx(v4), mx(v5), mx(v6), mx(v7), mx(v8),
                                      mx(v9), mx(v10), mx(v11), mx(v12)};

    std::vector<std::string> quotients = {"max std::size_t / max array size", cs(v0),
                                          cs(v1), cs(v2), cs(v3), cs(v4), cs(v5), cs(v6),
                                          cs(v7), cs(v8), cs(v9), cs(v10), cs(v11), cs(v12)};

    std::size_t max1 = maxColWidth(types);
    std::size_t max2 = maxColWidth(sizes);
    std::size_t max3 = maxColWidth(quotients);

    for (std::size_t i = 0; i < types.size(); ++i) {
        while (types[i].length() < (max1 - 1)) {
            types[i] = " " + types[i];
        }

        types[i] += " ";

        for  (int j = 0; sizes[i].length() < max2; ++j)
            sizes[i] = (j % 2 == 0) ? " " + sizes[i] : sizes[i] + " ";

        for  (int j = 0; quotients[i].length() < max3; ++j)
            quotients[i] = (j % 2 == 0) ? " " + quotients[i] : quotients[i] + " ";

        std::cout << "|" << types[i] << "|" << sizes[i] << "|" << quotients[i] << "|\n";
    }

    std::cout << std::endl;

    std::cout << "N.B. max std::size_t is: " <<
        std::numeric_limits<std::size_t>::max() << std::endl;

    return 0;
}

내 macOS (clang 버전 5.0.1)에서 다음을 얻습니다.

|  data types | approx max array length | max std::size_t / max array size |
|        bool |   9223372036854775807   |             2.000000             |
|        char |   9223372036854775807   |             2.000000             |
|      int8_t |   9223372036854775807   |             2.000000             |
|     int16_t |   9223372036854775807   |             2.000000             |
|     int32_t |   4611686018427387903   |             4.000000             |
|     int64_t |   2305843009213693951   |             8.000000             |
|     uint8_t |   9223372036854775807   |             2.000000             |
|    uint16_t |   9223372036854775807   |             2.000000             |
|    uint32_t |   4611686018427387903   |             4.000000             |
|    uint64_t |   2305843009213693951   |             8.000000             |
|      size_t |   2305843009213693951   |             8.000000             |
|      double |   2305843009213693951   |             8.000000             |
| long double |   1152921504606846975   |             16.000000            |

N.B. max std::size_t is: 18446744073709551615

ideone의 GCC 8.3 내가 얻을 :

|  data types | approx max array length | max std::size_t / max array size |
|        bool |   9223372036854775744   |             2.000000             |
|        char |   18446744073709551615  |             1.000000             |
|      int8_t |   18446744073709551615  |             1.000000             |
|     int16_t |   9223372036854775807   |             2.000000             |
|     int32_t |   4611686018427387903   |             4.000000             |
|     int64_t |   2305843009213693951   |             8.000000             |
|     uint8_t |   18446744073709551615  |             1.000000             |
|    uint16_t |   9223372036854775807   |             2.000000             |
|    uint32_t |   4611686018427387903   |             4.000000             |
|    uint64_t |   2305843009213693951   |             8.000000             |
|      size_t |   2305843009213693951   |             8.000000             |
|      double |   2305843009213693951   |             8.000000             |
| long double |   1152921504606846975   |             16.000000            |

N.B. max std::size_t is: 18446744073709551615

이것은 이론적 인 한계이며 대부분의 컴퓨터에서이 한계에 도달하기 훨씬 전에 메모리가 부족하다는 점에 유의해야합니다. 예를 들어 charon 유형의 gcc경우 최대 요소 수는 max ofstd::size_t . 이것을 시도 하면 오류가 발생합니다.

prog.cpp: In function int main()’:
prog.cpp:5:61: error: size of array is too large
  char* a1 = new char[std::numeric_limits<std::size_t>::max()];

마지막으로 @MartinYork가 지적했듯이 정적 배열의 경우 최대 크기는 스택 크기에 의해 제한됩니다.


0

이미 지적했듯이 배열 크기는 하드웨어 및 OS (man ulimit)에 의해 제한됩니다. 그러나 소프트웨어는 창의성에 의해서만 제한 될 수 있습니다. 예를 들어, "배열"을 디스크에 저장할 수 있습니까? 긴 long ints가 정말로 필요합니까? 정말로 조밀 한 배열이 필요합니까? 심지어 배열이 필요합니까?

간단한 해결책 중 하나는 64 비트 Linux를 사용하는 것입니다. 어레이에 물리적으로 충분한 램이없는 경우에도 프로세스에서 사용 가능한 가상 메모리가 실제 메모리보다 훨씬 크기 때문에 OS는 마치 마치 메모리를 할당 할 수 있습니다. 어레이의 모든 항목에 실제로 액세스해야하는 경우 디스크에 저장해야합니다. 액세스 패턴에 따라이 작업을 수행하는보다 효율적인 방법이있을 수 있습니다 (예 : mmap () 사용 또는 파일에 데이터를 순차적으로 저장하는 경우 (이 경우 32 비트 Linux로 충분)).


2
흠, 디스크, 어레이 등 .. 누구나 가상 메모리를 듣습니다 . 가상 메모리 를 지원하는 OS 는 하드 디스크와 같은 메모리 용 외부 장치를 사용하기 시작하고 내부 메모리와 청크를 교체합니다.
Thomas Matthews

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.