문제

나는이 코드를 우연히 발견했다. this ~이다 null. 나는 이것이 어떻게 될 수 있는지 모르겠다 null

그것은 다음과 같은 일반적인 메소드 호출 내에 있습니다

myObject->func();

내부에 MyObject::func() 우리는 가지고 있습니다

if (!this) { return false; }

내가 던질 첫 번째 줄을 가질 수있는 방법이 있습니까? NullPointerException 안으로 들어가는 대신 null(?) 방법?

도움이 되었습니까?

해결책

당신이 가지고 있다면:

MyObject *o = NULL;

o->func();

다음에 일어나는 일은 여부에 따라 다릅니다 func 가상입니다. 그렇다면 VTable을 얻기 위해 객체가 필요하기 때문에 충돌합니다. 그러나 가상이 아닌 경우 호출은이 포인터가 Null로 설정된 것으로 진행됩니다.

표준에 따르면 이것이 "정의되지 않은 동작"이라고 생각합니다. 따라서 모든 일이 발생할 수 있지만 일반적인 컴파일러는 코드를 생성하여 포인터가 무효인지 확인하지 않습니다. 잘 알려진 일부 라이브러리는 내가 설명한 행동에 의존합니다. MFC는 다음과 같은 기능이라는 기능이 있습니다. SafeGetHandle 이 경우 Null 포인터에서 호출 될 수 있으며이 경우 Null을 반환합니다.

재사용 가능한 헬퍼 기능을 작성하고 싶을 수도 있습니다.

void CheckNotNull(void *p)
{
    if (p == NULL)
        throw NullPointerException();
}

그런 다음 함수가 시작될 때이를 사용하여 다음을 포함하여 모든 인수를 확인할 수 있습니다. this:

CheckNotNull(this);

다른 팁

이러한 종류의 오류 (디자인 별)를 포획하는 방법은 포인터 래퍼 클래스를 사용하는 것입니다 ( shared_ptr) 그것은 널 포인터 논쟁으로 창조에 던져집니다. 그것은 또한 불쾌감을 느끼면 던져 질지 모르지만, 그것은 조금 늦었습니다 - 아무것도 아닌 것보다 낫습니다.

if(this == null)
   throw new NullPointerException;
if(!this)
   return false;

(이 == null)은 표준에 따라 정의되지 않은 동작입니다. 나는 당신 이이 점검을 제거해야한다고 생각합니다 :)

다음과 같은 전화를한다고 가정합니다.

((CSomeClass*) 0)->method();

동작은 이미 정의되지 않았으므로 왜 csomeclass :: method에서 this == null을 확인하는 이유는 무엇입니까?

편집 :멤버 변수를 사용하지 않으면 컴파일러가 처리한다고 가정하지만 가상 테이블 포인터는 어디에서 찾을 수 있습니까? 이 경우 수업은 다형 요법을 사용할 수 없습니다.

가능합니다 this 널 이 코드가 객체가 아직 초기화되지 않았거나 삭제되지 않은 레이스 조건을 (나쁜) 감지하려고한다고 생각합니다.

이 포인터는 다음과 같은 경우에 무효가 될 수 있습니다.

class Test
{

public:
    bool f();

private:
    int m_i;
};


bool Test::f()
{
    if(!this)
    {
        return false;
    }

    m_i = 0;
    return true;

}


int main(int argc, char **argv)
{
    Test* p = new Test;
    delete p;
    p = NULL;

    p->f();
}

누군가 액세스 위반 예외를 피하기 위해 빠른 해킹을했다고 생각합니다.

이 == null은 삭제 된 객체에서 메소드를 호출하는 경우에만 발생하거나 무언가가 메모리에 쓰는 경우 (특히이 포인터의 객체를 덮어 쓰지 않도록하는 경우) 발생해야합니다.

코드와 같이 일을하려고하지 않고 코드에 실제로 무엇이 잘못되었는지 조사해야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top