2014-10-12 2 views
0
char *s = sbrk(some_num); 
if (s != (char *)-1) {  
    some_struct = (SomeStruct *)s; 
    some_struct->num = 8; //num is an int [*SEG FAULT OCCURS ON THIS LINE*] 
} 

디버깅 사용하여 gdb를하는 경우 :분할 오류 모든 값은 NULL이 아닌

p some_struct => (SomeStruct *) 0xef7100 
p some_struct->num => 0 

A는, 뭔가가 NULL 인 경우 SEG 오류가 발생하는 것을 이해 이전의 Q /에서,하지만이 예에서는 , some_struct, some_struct-> num 및 8은 모두 이 아닌입니다.

왜 분할 오류가 발생합니까? some_struct-> num을 int 값으로 설정할 수 있습니까?

+1

Seg 오류는 포인터가 NULL 일 때만이 아니라 메모리에 잘못된 액세스 권한이있는 경우입니다. – SHR

+2

실제로 확인할 수있는 최소한의 코드 만 게시하십시오. – BLUEPIXY

+0

0xef7100이 유효한 포인터가 아니거나 num이 int가 아닌 int * –

답변

1

포인터 some_struct는 유효한 메모리를 가리켜 야합니다. some_function 함수가 일부 local volatile 변수에 대한 포인터를 반환하면 some_function이 종료 될 때 변수가 손실됩니다.

segfault를 피하려면 some_function의 로컬 변수를 정적으로 선언하거나 some_function이 malloc을 호출하도록하여 힙에서 메모리를 할당 할 수 있습니다. some_function이 malloc으로 메모리를 할당하면 나중에 메모리가 해제되는지 호출자가 책임지게됩니다.

segfault를 피하는 또 다른 방법은 포인터를 지역 변수가 아니라 전역 변수로 반환하는 것입니다. 그러나 대부분의 사람들은 글로벌 변수를 피해야한다는 것에 동의합니다.

+0

감사합니다. 코멘트 작성자의 요청으로 좀 더 자세한 내용을 추가했습니다 : some_function -> sbrk (some_num) – GangstaGraham

+0

전체 구조체에 충분한 메모리를 할당하지 않으면 구조체의 외부에있는 부분에 쓸 때 segfault가 발생할 수 있습니다 할당 된 메모리 –

+0

또한 sbrk 대신 malloc을 사용하여 메모리를 할당하는 것이 이식성이 높습니다. –

0

오늘날 대부분의 현대 OS의 근간을 이루는 가상 메모리의 개념에 익숙해지는 것이 가치가 있습니다.

가상 메모리가있는 OS에서 모든 메모리 주소 (실제로 가상 주소)는 전화 번호와 유사하여 약 10 자리를 조합 할 때 전화를 걸 수 없습니다.

전화 번호부에 나열된 전화 번호로만 전화를 걸면됩니다.

그렇지 않으면 "죄송합니다.이 번호는 현재 서비스가 중단되었습니다."라는 메시지가 표시됩니다.

마찬가지로, 각 프로세스의 "페이지 테이블"에 나열된 가상 주소 (항상 자동으로 투명하게 OS에 의해 관리 됨) 만 프로세스가 액세스 할 수 있습니다.

SEGV는 OS의 "죄송합니다.이 가상 주소는 현재 서비스되지 않습니다."라고 말합니다.

malloc (및 sbrk)은 기본적으로 OS에 지정된 크기의 메모리 청크를 할당하고 해당 주소를 페이지 테이블에 등록하도록 요청할 수 있습니다.

관련 문제