2012-09-04 2 views
0

가능한 중복 접근 :세그먼트 오류 동안 메모리 영역을

: 리눅스 M/C에이 매우 작은 프로그램을
Invalid read/write sometimes creates segmentation fault and sometimes does not

내가 malloc에 ​​몇 가지 실험을하고 있었다를 썼다

int main(){ 
    int *p=NULL; 
    p = (int *)malloc(10); 
    *(p + 33*1000) = 5; 
    free(p); 
    return 0; 
    } 

이 프로그램은 세그먼트 화 오류를주지 않지만 5 행을이로 변경하면* (p + 34 * 1000) = 5; 그런 다음 세그멘테이션 오류가 발생합니다. 내 시스템에서 페이지 크기는 4K입니다.

p 이후에 약 128Kb (34 * 1000은 약 128K)에서 분할 오류가 발생하는 이유를 설명 할 수 없습니다.

누군가가 리눅스에서 메모리 관리의 관점에서 이것을 설명 할 수 있다면 좋을 것입니다.

답변

4

당신은 당신이 정의되지 않은 동작 모두 *(p+33*1000), *(p+34*1000)p에 할당 된 메모리를 넘어 액세스 할 수 있습니다. 그것이 "작동"하거나 충돌 할 수 있거나 어떤 일이 발생할 수 있으므로 추론 할 수 없습니다.

+1

나는 의도적으로 내가 할당하지 않은 메모리 영역에 액세스하고 있는데, 내 질문은 p + 34 * 1000에 대한 세분화 오류를주는 이유와 p + 33 * 1000에 대한 오류를주지 않는 것입니다. – ankur

+0

앞서 말했듯이 C 언어 표준을 따르지 않는 정의되지 않은 동작을 추론 할 수 없습니다. 앞으로는 p + 33000에 액세스 할 때 충돌이 발생할 수 있으며 * p * 33000에서 작동하는 것처럼 보입니다. –

+0

읽어보기 : http://en.wikipedia.org/wiki/Undefined_behavior –

2

자신이 할당하지 않은 메모리를 수정합니다. 작성한 주소가 배열 한도를 초과합니다. 배열 경계를 넘어서 작성할 때마다 segfault의 위험을 감수해야합니다. 이는 메모리 위치에 따라 다릅니다. 그것은 주소에 따라 segfault하지 않을 수도 있지만 이것이 좋은 일이고 예측할 수없는 결과입니다.

2

이 프로그램은 (C 표준에 따라) 정의되지 않은 동작을 나타내며 엄밀히 말하면 설명 할 내용이 없습니다.

언어 표준은 특정 플랫폼에서 저수준으로 메모리 관리를 구현하는 방법을 설명하지 않습니다. 일부 메모리 영역은 명시 적으로 할당하지 않아도 액세스 할 수 있습니다.

0

10 개의 정수를위한 공간을 할당 한 후에는 *(p+0), *(p+1), ..., *p(p+8), *p(p+9)으로 10을 역 참조 할 수 있습니다. 더 이상 당신이 할당 한 것의 범위를 벗어납니다.

다른 곳에서 역 참조한다는 것은 잘못된 포인터를 사용하려고 시도하고 세그먼트 오류가 발생했음을 의미 할 수 있습니다.

+0

@PaulR 잘못된 용어를 수정했습니다. – acraig5075

0

시스템의 사용 가능한 메모리가 그럴 수도 있습니다. 이 경우 모두 < = 33 * 1000이 통과하고 모두> = 34 * 1000이 실패합니다.