2012-12-05 2 views
0

나는 Moai 소스 코드를 읽고 있었는데 왜 이것이 충돌을 야기하는지에 대해 궁금해졌습니다.null 포인터의 참조 해제로 인해 충돌이 발생하는 이유는 무엇입니까?

나는 그 발췌 문장을 정말로 이해하지 못합니다. 파일 A에서

:

#define UNUSED(p) ((void)p) 

파일 B에서는 :

//----------------------------------------------------------------// 
/** @name crash 
    @text Crashes Moai with a null pointer dereference. 

    @out nil 
*/ 
int MOAISim::_crash (lua_State* L) { 
    UNUSED(L); 

    int *p = NULL; 
    (*p) = 0; 

    return 0; 
} 

는 편집 :

내가 이해하지 못하는 있었는지의 부분은 "존중"이 무엇을 의미하는지 생각합니다. 그래서 당신이 그것을 당신의 대답에 넣으면 그것은 굉장 할 것입니다.

+0

'UNUSED (L);은'L '이 사용되지 않는다는 경고를 표시하지 않습니다. 'return 0;'은 우리가 함수가 정수를 리턴했다고 말했기 때문에 컴파일러를 행복하게 유지하는 것입니다. (물론, 실제로 돌아 오지 않습니다.) –

+0

나는 매우 명확하고 기술적 인 질문을했습니다! – speeder

+0

또한 충돌이 일어나는 줄은 다소 명백합니다. 어떻게, 왜, 구체적으로 ... 알고 싶습니다. (* p), =, 0 또는 = 0입니다. = 1이면 작업? 등등. – speeder

답변

12

충돌이 널 포인터의 역 참조에 의해 발생 :

(*p) = 0; // <--- Crash 

의견에서 지적 또한, 사용하지 않은 매크로는 대부분의 컴파일러 줄 것이라고 경고 "사용되지 않는 매개 변수를"억제 만이 .

그것은에 의해 경고를 방지하는 것이 가능하다, 간단하게, 변수 이름을 지정하지 않는 다음과 같이

int MOAISim::_crash (lua_State*) 
{ 
    int *p = NULL; 
    (*p) = 0; 

    return 0; 
} 

또한 명심 가치가 위의 것을하지 보장 충돌. 널 포인터를 참조 해제하는 32 비트 콘솔 중 하나에서 실제로 숫자 "3"이 생성되었습니다. 이렇게하면 null 역 참조를 찾기가 어렵지 만 일반적으로 레지스터에 3 명이 앉아있는 것을 보았을 때 방금 잘못 나온 것에 대해 좋은 추측을 할 수 있습니다.

역 참조는 필수적으로 주어진 포인터에 저장된 값을 요구합니다. 포인터가 유효하지 않으면 (즉, 프로세스가 소유하지 않은 메모리 위치를 가리키는 경우) 충돌이 발생합니다. Windows에서는이를 액세스 위반 (0xC0000005)이라고합니다. Linux에서는 Segmentation Violation, SIGSEGV입니다.

int MOAISim::_crash (lua_State* L) { 
    ((void)L); 

    int *p = NULL; 
    (*p) = 0; 

    return 0; 
} 

((void)L) 라인 L을 평가하고 그 결과를 던져 : 컴파일러의 기능은 다음과 같습니다 있도록

See also

+0

"3"예제가 마음에 들지만, UB가 어떻게 작동하는지에 대한 또 다른 좋은 예입니다. "충돌 할 수도 있고, 불타거나, 3을 얻을 수도 있습니다." –

3

매크로, 코드에서 대체됩니다. 그러나 충돌은 해당 줄에서 오는 것이 아니며 NULL 주소 인 (*p) = 0에 할당 된 것입니다.

1
int *p = NULL; 
(*p) = 0; 

두 번째 줄은 nullptr 포인터를 참조 해제하는 동작입니다. 플랫폼에서 응용 프로그램을 충돌시키는 사실은 정의되지 않은 동작의 한 형태 일뿐입니다. 제 생각에는 좋은 점은 버그를 더 빨리 발견 할 수 있기 때문입니다.

관련 문제