2014-04-10 5 views
2
#include <stdio.h> 
#include <stdlib.h> 

int noOfIntegers = 2; 

struct stack { 
    int *s; 
    int top; 
} st; 

void push(int item) { 
    st.top++; 
    st.s[top] = item; 
} 

int main() { 
    st.s = malloc (2 * (sizeof(int))); 
    st.top = -1; 
    push(1); 
    push(2); 
    push(3); 
    return 0; 
} 

이유는 이해가 안 돼요 내가의 malloc'd 공간을 가지고 있고 배열에 3을 삽입하여 포인터가 가리키고 있습니다.왜 세분화 위반 오류가 발생하지 않습니까?

+5

이것은 정의되지 않은 동작 (사례의 범위를 벗어나는 요소에 액세스)의 장점입니다. 운 좋게도 예상대로 작동 할 수 있습니다. 운이 좋으면 큰 소리로 폭탄을 터뜨릴 것입니다. – pmg

+0

SEGFALT를 만드는 것보다 힙을 손상시킬 가능성이 큽니다. 모든 메모리를 세 심하게 관리하는 8051과 같이 작은 메모리 구현에서 사용하려고하면 그렇게 할 수 있습니다. 그러나 대부분의 32+ 비트 주소 공간에서 할당 단위는 일반적으로 16 바이트 (또는 그 이상) 단위로 관리되므로 요청한 바이트 이상으로 이동해도 문제가 발생하지 않습니다. – wallyk

+1

세그멘테이션 오류가 발생했다고 생각하십니까? 당신의 믿음이 당신의 프로그램이 그런 결함을 만들어 내야한다는 결론에 잘못 이끌었 기 때문에, 당신의 믿음이 부정확하다는 것이 좋은 것입니다. 따라서 더 나은 질문은 "세분화 오류의 원인은 무엇입니까?" 나는이 질문이 관련 위키 백과 페이지를 읽음으로써 대답 될 수 있음을 주목한다. –

답변

3

malloc은 힙 메모리에서 공간을 할당합니다. 힙에 2 ints을 할당하고 3 ints이라고 씁니다.

프로그램 메모리는 일반적으로 메모리 관리자를 위해보다 효율적인 크기의 청크로 할당됩니다.

요청 1 바이트? 당신은 아마 8 바이트 있어요.
요청 7 바이트? 당신은 아마 8 바이트 있어요.
요청 14 바이트? 아마 16 바이트가 있습니다.
(아니면 최소한 그 16 바이트 ...) 당신은 당신이 실제로 요청한 메모리에 액세스를 보장하지만 때때로을 유발하지 않고 몇 바이트 그 이상 쓸 수 있습니다

문제. 과도한 쓰기가 안전하다는 약속은 없습니다. 너 에 seg-fault가 생길 수도 있습니다! 그렇지 않을 수도 있습니다!

1

운이 좋다면 segfault 오류가 발생하거나 아무 것도 표시되지 않습니다.

다른 변수에 의한 데이터 사용을 포함 할 수있는 장소에 뭔가를 작성했습니다.

편집 : 당신이 당신의 programm에 대한 예약 된 메모리 공간에 작성하여 OS 아무것도 말하지 않는다 그러나 당신이 아마 10 000 시간을 계속하면 당신은 다른 프로그램과 OS 의지의 데이터를 삭제하기 때문에이 생산 및 오류하지 않습니다 다른 프로그램을 보호하기 위해 프로그램을 종료하십시오.

+0

그게 미안. 'segfault '가 발생하지 않는 이유는 무엇입니까? – AkshaiShah

+0

예약 된 메모리 공간에 다시 있기 때문에 발생하지 않습니다. – user43968

+1

프로세스의 가상 메모리 공간에 매핑되지 않은 주소를 읽거나 쓰려고 시도하는 경우에만 segfault가 발생합니다. 항목을 계속 누르고 있으면 segfault를 트리거하는 주소로 이동합니다. –

14

업데이트 :이 질문은 my ATBG column in May 2014의 영감을주었습니다. 좋은 질문에 감사드립니다!


지평선까지 펼쳐진 광대 한 지뢰밭을 상상해보십시오. 광산을 타고 오를 경우 붐, 차가 폭발합니다.

지뢰밭의 중간에는 4 천 개의 숫자가 매겨진 공백이있는 분지가없는 주차장이 있습니다. 각 주차장에는 번호가 있습니다. 각 칸에는 숫자가 있습니다. 제비의 일부는 서로 옆에 있고, 일부는 그렇지 않습니다.

주차장 관리자를 불러 8 칸을 요청하십시오. 당신은 당신의 공간이 로트 100, 공간 1234에서 1241 사이에 있다고 들었습니다.

당신은 당신의 차를 많은 사람들에게 운전하고, 1243 년 우주에서 차를 찾으며, 그 자리에 차를 주차시키고, 다른 사람의 차를 몰아냅니다.

왜 자동차가 폭발하지 않았습니까? 너는 지뢰밭이 아니기 때문에. 규칙을 어긴거야? 확실한. 다른 누군가의 주차 공간을 훔쳐갔습니다. 그러지 마. 아마 거기에서 그들의 차를 발견하지 못하면 화가 나있을 것이다. 하지만 그들은 너를 날려 버리지 않을거야.

당신은 그 차를 4003 지점에 몰아 넣습니다. 그러나 그 지점에는 4000 지점 만 있기 때문에 4000 지점에 운전 한 다음 오른쪽의 3 지점이 될 곳으로 주차장의 오른쪽을 주행해야합니다. 자리 4000.주차장 101 번에서 3 번 지점이되었습니다. 도난당한 차량을 주차하고 이전에 있던 차량을 훔칠 수 있습니다.

왜 자동차가 폭발하지 않았습니까? 너는 지뢰밭이 아니기 때문에.

다음으로 로트 100의 8003 지점을 찾으십시오. 로트 100의 끝까지가는 길 100 개를 통과하여 4000 개의 지점 만 있으면됩니다. 이번에는 당신은 지뢰밭으로 향합니다.

왜 자동차가 폭발합니까? 네가 지뢰밭에 있으니까.

이제는 소유하지 않은 메모리에 쓰는 것이 세그먼테이션 오류를 보장하지 않는 이유는 무엇입니까? 분할 오류는 "이 유효한 페이지가 아닌 메모리 페이지에 있습니다."을 의미합니다. 당신이 가정하지 않은 유효한 페이지의 일부를 사용한다면, 운영 체제는 그것을 알지 못합니다.

관련 문제