2013-03-15 1 views
1
int main() 
{ 
    int *a; // a = 0x4053c6 (a random address) 
    // this will cause the program to exit, and how do i know this memory can't be written ? 
    *a = 5; 
    return 0; 
} 

혼란스러워! 나는이 스 니펫이 항상 프로그램이 충돌하도록 유도 할까? 그리고이 프로그램이 처음부터 끝까지 실행할 수있는 경우가 있습니까?C++의 임의 메모리 블록에 쓸 때 예외를 잡는 방법

+0

직접 추적해야합니다. 이 경우'a'가 초기화되지 않았다는 것을 알기 때문에 포인터 값을 읽는 것은 정의되지 않은 동작입니다 (참조 된 위치에 쓰지 않고). – GManNickG

+0

'a'가 초기화되지 않았다는 것을 알고 있습니다. 그리고 대부분의 심사관은 경고를 발표 할 것입니다. 그러나'* a = 5'를 실행할 기회가 있는지 알고 싶습니다. – Ggicci

+1

@Ggicci : 그렇습니다. 정의되지 않은 동작은 어떤 일이 발생할 수 있음을 의미합니다. 야생 일치가있을 수 있다면 'a'는 예를 들어 따라서 자신의 주소와'* a'는 (프로그램을 알고있는 OS가 알고있는 한) 쓸 수있는 유효한 장소입니다. 그럼에도 불구하고'a'가 자신의 주소를 갖고 있으면 작동 할 것이라고 보장하지 않습니다 ... 정의되지 않은 동작에 대해서는 아무 것도 보장되지 않습니다. 다른 무해한 가능성도 있습니다. 'a'는 현재 사용되지 않는 스택 공간을 쉽게 가리킬 수 있습니다. –

답변

0

일반적으로 충돌이 발생하지만 보장되지 않습니다 (변수가 초기화되지 않았기 때문에 유효하거나 무효 한 값이 포함될 수 있습니다). C++ 예외로 인해 액세스 위반을 catch 할 수는 없지만 컴파일러는 확장을 제공합니다. 예를 들어, Visual C++에서는 SEH (Structured Exception Handling)를 사용할 수 있습니다.

#include <Windows.h> 
#include <iostream> 

using namespace std; 

int main() 
{ 
    int* p = reinterpret_cast<int*>(0x00000100); 

    __try 
    { 
     *p = 10; 
    } 
    __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) 
    { 
     cout << "Access violation" << endl; 
     return -1; 
    } 

    cout << *p << endl; 
} 
0

코드는 운영 체제에 따라 트랩이나 신호로 처리되는 액세스 위반이 있습니다. 당신은 그것을 처리 할 수 ​​있을지도 모르지만 당신이 나중에 많이 할 수있을 것 같지는 않습니다. (취급 후 일반적인 조치 과정은 정상적인 종료입니다.)

사례가 있음을 입증하는 데는이를 증명하는 것이 매우 어려울 것입니다. 초기화되지 않은 변수를 스택의 특정 주소 (예 : 풍자)로 설정하는 자체 컴파일러를 가질 수 있습니다. A의 값을하여 유사 초기화하는

한 가지 방법은 함수를 호출하는 것입니다

void func(int k) 
{ 
    int *a; 
    int b = 0; 
    if (k == 1) { 
     a = &b; 
    } 
    *a = 5; 
} 

당신은 (1) 다음 몇 번하고 FUNC를 시도 FUNC으로 시도 할 수있다 (2). 기회 a와 b가 같은 스택 영역을 재사용하고 실패하지 않습니다. 그러나 다시 기회입니다.