2010-06-16 6 views
5

이 코드는 배열 선언 중에 세그먼트 오류를 ​​생성합니다. 나는 이것이 왜 일어나는 지 혼란 스럽다. 나는 그것이 2^31 이하이고 정수 변수에 들어갈 수 있기 때문에 값으로 2000000000을 의도적으로 선택했습니다.C 프로그래밍, 왜이 큰 배열 선언이 세그먼테이션 결함을 생성합니까?

int main() 
{ 

    int nums_size = 2000000000; 

    int nums[nums_size]; 

    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 


    return 0; 

} 

답변

21

글쎄, 한 가지는 20 억 개의 정수입니다. 플랫폼에 32 비트 주소 공간이 있고 int 크기가 4 바이트 인 경우 (일반적으로 32 비트 플랫폼의 경우) 해당 정수를 마침표로 저장할 수 없습니다.

자동 변수가있는 스택에서 사용할 수있는 공간이 너무 많습니다.

정말로 큰 배열이 필요한 경우 malloc()을 사용하여 불연속 적으로 배열을 할당해야합니다. 그렇게 할 경우 free()을 사용하여 해제해야합니다!). 이것이 불가능 -

+0

그렇지 않은 경우에도 32 비트 플랫폼에서 2000000000 * 4 = 8,000,000,000 바이트입니다. 그것은 거의 2^33이며 사용 가능한 메모리 이상입니다. –

+0

@Chris : 예 - 제가 게시 한 후에까지 실제로 0을 계산하지 않았습니다. 그것은 많은 정수입니다! –

+0

또한 정적 저장 기간이있는 매우 큰 배열을 할당하는 것이 일반적으로 가능합니다. – caf

4
int nums_size = 2000000000; 

int nums[nums_size]; 

int 타입의 2,000,000,000 바이트를 의미하지 않습니다, 당신이 거의 소모 8GB의 메모리를하는 것을 의미 32 비트 플랫폼에서 int 형의 2000000000 개 요소를 의미한다.

+0

... 스택에!- 카붐! –

3

스택에 거대한 배열을 할당하고 있습니다. 실제로 C/C++ 컴파일러는이를 올바르게 처리하지 못합니다.

globals (전역 적으로 메모리를 매핑 할 때 정적으로 공간을 할당 함) 또는 malloc 어레이로 전환하여 도망 갈 수 있습니다.

물론, 한 번에 물어 보는 것은 여전히 ​​많은 기억이지만, 적어도 내가 언급 한 방법은 segfault를 피할 것입니다.

+1

컴파일러가 2^32 메모리 크기 안에 있으면 올바르게 컴파일러에서 처리하지만 운영 체제에서 스택이 그만큼 커지지 않게합니다. –

+0

C/C++뿐만 아니라 스택 기반 할당을 수행하는 거의 모든 언어 (거의 모든 언어) – Spudd86

0

이 버전은 내 PC에 잘 실행 :

const int nums_size = 2000000000; 
int nums[nums_size]; 

int main() 
{ 
    int i; 
    for(i = 0; i < nums_size; i++) { 
     nums[i] = i; 
    } 

    return 0; 
} 

(. 음, 그것은 시작 솔직 벌금을하자, 곧 교체로 들어갑니다.)

+0

그리고 64 비트 플랫폼에서 실행되는 버전을 추측하고 있습니다. 그의 2^31 논평에서 그는 확실히 64 비트 OS를 실행하지 않습니다. –

+0

-1 (농담)보다 더 많은 메모리를 가지고 있습니다. – cdonner

+0

@Chris the 2^31 주석은 32 비트인지 64 비트인지를 알려주지 않습니다. 나는 gcc가 64 비트 플랫폼에서 32 비트 정수로 기본 설정되어 있다고 생각한다. – sigfpe

2

지역 변수는 스택에 할당된다 . 응용 프로그램에 제공되는 고정 된 크기의 스택 공간 (일반적으로 1MB-8MB, OS에 따라 다름)이 있습니다. 일반적인 규칙은 malloc()을 사용하여 많은 양의 데이터를 할당하는 것입니다.

1

귀하의 질문에 대한 답변은 간단합니다 : stackoverflow. 아니, 사이트가 아니라 "스택 오버플로"의 실제 프로세스입니다. 해당 배열을 저장하기에 충분한 stack이 없습니다. 저것과 같이 쉬운. 메모리가 제한된 시스템에서이를 수행하는 것은 순수한 광기입니다. 또한 this question을 참조하십시오.

관련 문제