2011-10-05 6 views
8

일부 데이터 블록에 액세스하기 위해 포인터를 사용하는 코드가 있습니다. 드문 경우지만 데이터 블록의 일부 구성원이 비어 있고 결과적으로 포인터가 매달리게됩니다. 사실, 나는 올바른 포인터를 얻지 만 포인터로 무엇인가를하려고 할 때 프로그램이 충돌합니다.포인터가 매달려 있는지 확인하는 방법이 있습니까?

일반적인 조언은 이러한 유형의 사용을 피하는 것입니다. 그러나 슬프게도, 내가 사용하는 프레임 워크는 이러한 유형의 데이터 액세스 방법을 사용해야합니다.

어떤 작업을 수행하기 전에 포인터가 유효하지 않은지 "확인"할 수있는 방법이 있습니까? 포인터가 NULL과 같지 않은지 확인하는 것은 분명히 작동하지 않았습니다. 또한 시도 :

try 
{ 
    CString csClassName = typeid(*pMyPointer).name(); // Check error condition 
    // The line below fails due to dangling pointer (data block is not valid). 
    hr = pMyPointer->MyPointerMethod(); 
} 
catch(bad_typeid) 
{ 
    return E_FAIL; 
} 
catch(...) 
{ 
    return E_FAIL; 
} 

올바른 방법입니까?

답변

5

원시 포인터의 유효성을 검사 할 방법이 없습니다. 잘못된 포인터는 액세스 할 때 실패하지 않을 수도 있습니다. 원시 포인터를 사용하는 대신 스마트 포인터의 형식을 사용해야합니다.

+0

내 포인터가 클래스에 정적이어야합니다. 여전히 괜찮습니다. 스마트 포인터를 사용한다면? – Nikhil

+0

그건 전혀 문제가되지 않습니다. 스레드 안전 문제를주의해야하지만 스마트 포인터와 원시 포인터는 다르지 않습니다. –

+2

나는 그것이 중요하다고 생각하지 않는다. 귀찮게하는 유일한 방법은 프레임 워크가 사전 통지없이 포인터를 매달 수 있는지 여부입니다. 보시다시피, 스마트 포인터에서 원시 포인터를 추출하여 프레임 워크에 전달해야합니다. 포인터가 호출 후에도 유효한 상태를 유지하거나 유효하지 않으면 알릴 것입니다. 괜찮 으면 이동하십시오. – Septagram

7

나는 잘못된 방향을보고 있다고 생각합니다. 포인터를 올바르게 초기화하지 않았거나 너무 일찍 삭제하거나 포인터가 삭제 된 후에 다시 사용하려고하는 버그가있을 수 있습니다. 그렇다면 버그 숨기기 방법을 찾는 것보다 버그가 발생하는 이유를 파악하고 버그를 수정하는 데 집중해야합니다.

typeid 연산자와 함께 사용하는 방법은 유효하지 않습니다. 가상 함수가없는 형식의 개체의 경우 typeid 연산자는 포인터의 정적 형식을 기반으로 컴파일 할 때 확인됩니다. 하나 이상의 가상 함수를 포함하는 객체의 경우 런타임에 해석되지만 유효하지 않은 포인터로 typeid(p)을 호출하면 정의되지 않은 동작이 발생하고 작동하는 것과 같은 방식으로 충돌이 발생할 수 있습니다.

제안 된 스마트 포인터의 사용은 라이브러리가 실제로 수행하는 작업과 스마트 포인터를 항상 전달할 수 있는지 여부에 달려 있습니다. 일반적으로 메모리 관리를 위해 스마트 포인터를 사용하는 것이 좋습니다. 그러면 포인터가 올바르게 초기화되고 (문제가 초기화되면 수정 됨) 더 이상 수동으로 delete이 없으므로 문제가 발생한 경우 더 이상 발생하지 않는 조기 삭제가 있습니다. 하지만이 방법으로 문제를 해결할 수는 있지만 포인터가 응용 프로그램에서 유효하지 않은 이유를 이해해야 할 필요가 있다고 생각합니다. 문제가 큰 증상 일 수 있습니다.

이제 포인터가 매달려 있는지 여부를 확인하는 방법에 대한 원래 질문에 대해서는 프로그램에서 수행 할 수 없지만 메모리 디버거 (Linux, Purify 또는 다른 세트의 valgrind)에서 프로그램을 실행할 수 있습니다 Linux에서) 도구는 포인터가 초기화되지 않았는지 또는 잘못 사용하기 전에 메모리를 시스템에 릴리스했는지 여부를 확인하는 데 도움을 줄 수 있습니다.

+0

자세한 설명 주셔서 감사합니다. 나는 버그를 숨기는 대신 해결책을 찾아야한다는 것을 이해할 수 있습니다 ... 그러나 짧은 시간에 변경할 수없는 프레임 워크 설계의 허점이 있습니다. 그래서 나는 당분간 해결 방법을 찾고있었습니다. 스마트 포인터로도 시도했지만 제대로 작동하지 않았습니다. – Nikhil

1

스마트 포인터가 필요하지 않습니다. 이것들은이 문제를 다루기위한 가능한 한 방법 일뿐입니다.

상호 참조를 사용할 수 있습니다. 참조 된 개체 (참조) 내에서 참조하는 개체 (참조 자)에 대한 참조 목록. 참조를 할당 해제 할 시간이되면 먼저 해당 참조 자 목록을 실행하고 참조를 가리키는 모든 속성을 설정합니다 (일반적으로 미리 어떤 속성이 있는지 알고 싶어합니다). 그런 다음 할당을 해제합니다. 참조.

관련 문제