0

delete가 어떻게 작동하는지 알고 싶습니다. 주 기능에서 cfactobject을 삭제했습니다. 하지만 여전히 cfact->Hello()은 오류를 발생시키는 대신 작동합니다. 삭제하는 동안 발견 한 디버그 동안 cfact 메모리를 해제합니다. 최대한 factory* c2fact = newfun.Newfun("c2_fact"); 라인 실행 cfact 일부 메모리 위치를 가져옵니다.C++에서 delete 키워드 opearation과 혼동을 느낍니다.

어떻게? 개념을 이해하는 데 나를 도우십시오.

class factory{ 

public: 
    virtual void Hello() = 0; 
}; 
class c_fact: public factory 
{ 
public: 
    void Hello(){ 
    cout << "class c_fact: public factory"<<endl; 
    } 
}; 
class c2_fact: public factory 
{ 
public: 
    void Hello(){ 
    cout << "class c2_fact: public factory"<<endl; 
    } 
}; 

class callFun{ 
public: 
    virtual factory* Newfun(string data) 
    { 
     if(data == "c_fact") 
      {return new c_fact;} 
     else 
      {return new c2_fact;} 
    } 
}; 
class newFun:public callFun{ 
public: 
    factory* Newfun(string data) 
    { 
     if(data == "c_fact") 
      {return new c_fact;} 
     else if (data == "c2_fact") 
      {return new c2_fact;} 
    } 
}; 
int main() 
{ 
    newFun newfun; 
    factory* cfact = newfun.Newfun("c_fact"); 
    delete cfact;        //Deleted the instance 
    factory* c2fact = newfun.Newfun("c2_fact"); 
    cfact->Hello();//Still it prints the output 
    c2fact->Hello(); 
    system("pause"); 
    return 0; 
} 
+0

예상되는 결과는 무엇입니까? 삭제 된 객체에서 함수를 호출하고 있습니다. 이것은 정의되지 않은 동작이며 출력 인쇄를 포함하여 모든 일이 발생할 수 있습니다. –

+0

@PeterWood : 'cfact-> Hello();'가 실패하기를 원합니다. 우연히 나는이 행동을 보았다. 그래서, 나는 물어볼 생각을 이해할 수 없었다. –

+0

가상 소멸자를 사용해야합니다. – Jeka

답변

5

delete 실제로 가리키는 내용이 무효화되지는 않습니다. 단지 은 메모리가 다른 것 ()에 사용될 수 있고 프로그램이 더 이상 필요하지 않다는 것을 OS에 알려줍니다.

다른 데이터로 덮어 쓰지 않으면 데이터는 여전히 메모리에 저장되며 여전히 액세스 가능이됩니다. 이것은 개발 단계에서 발견되지 않고 나중에 발견되는 많은 버그의 원인입니다.

현재 작동한다고해서 항상 작동한다는 것을 의미하지는 않습니다. 예를 들어 코드를 다른 시스템으로 옮기거나 컴퓨터를 다시 시작하면 코드가 분리 될 수 있습니다.

delete 이후에 포인터를 NULL으로 설정하는 것이 좋습니다. 또는 smart pointers을 사용하는 것이 좋습니다.

+2

'delete'는 가리키는 내용을 무효화 할 수 있습니다. 표준에 따르면 필요하지 않습니다. 구현 세부 사항입니다. –

+0

또한 delete는 OS에 메모리를 반환하지 않으며 응용 프로그램 메모리 풀로 만 반환합니다. 응용 프로그램 메모리 풀은 동일하지 않을 수 있습니다. 이는 구현 세부 사항이기도합니다. 하지만 삭제가 직접적으로 일반 사용자 공간 환경에서 OS 메모리 처리를 거치면 나쁜 구현이 될 수 있습니다. – Devolus

2

이것은 정의되지 않은 동작이며, 이는 Hello 메서드가 클래스 변수를 사용하지 않아서 this 포인터를 사용하지 않기 때문에 가능합니다. 시도 Hello에서 this를 출력하고 delete에 전화 후 유효하지 않은 포인터를 참조해야합니다

std::cout << std::hex << this << << std::endl ; 

을 내 테스트 경우는 삭제 된 포인터를 역 참조 delete

1

후 다시 0로 온다 정의되지 않은 동작입니다. 즉, "일하는"것으로 보이는 프로그램을 포함하여 모든 일이 발생할 수 있음을 의미합니다. 그러한 행동에 의존 할 수는 없습니다.

1

메모리를 삭제하면 메모리가 삭제됩니다. 그러나 내용은 일반적으로 변경되지 않으므로 해당 메모리에 기록 된 내용은 삭제 후에도 그대로 남아 있지만 다른 기능으로 가져 와서 자신의 데이터로 덮어 쓸 수 있기 때문에 내용이 얼마나 오래 남아 있는지 알 수 없습니다.

일부 컴파일러에서는 디버그 모드로 컴파일 할 때 메모리가 표시되므로 삭제 된 포인터를 다시 사용하여 오류를 감지 할 수 있습니다. 그러나 이것이 반드시 기본값은 아닙니다. 따라서 삭제 된 포인터를 재사용해서는 안됩니다.

1

죄송합니다. 말씀 드릴 수 없습니다 ... 내가 코드를 컴파일하고 해당 c2fact을 관찰 할 수 방금 파괴 cfact가 대체 (출력

클래스 c2_fact입니다 : 공공의 공장

클래스 c2_fact : 공공 공장 ) BTW

"cfact-> Hello();"를 입력하면 c2fact를 만들기 전에 mem 블록이 어떤 객체에도 영향을 미치지 않기 때문에 프로그램이 중단 될 수 있습니다. 이 동작은 메모리 모니터링 및 기타 실행중인 프로세스에 따라 달라질 수 있습니다. ...

다른 답변 (이름이있는 것 중 하나)이 사용자가 찾은 정보를 제공했기를 바랍니다.

+0

키워드는 "... MAY 충돌 ..."입니다. 이 프로그램은 다소 짧고 많은 일을하지 않기 때문에 주목을받지 못할 가능성이 있습니다. 물론 그것은 컴파일러이고 심지어 라이브러리에 의존적이다. 즉각적으로 중단 될 수도 있고, 수년간 프로덕션 코드에서 작동하고 코드가 완전히 다른 곳에서 충돌 할 수도 있습니다. – Devolus

+0

Arf 나는 당신의 의견을 업 그레 이드 할 수 없다 ... 그리고 사실 나는 아마 스스로를 고쳐야한다. "c2fact를 만들기 전에"cfact-> Hello(); "를 입력하면 프로그램이 중단됩니다." 난 그냥 Win7을 사용하여 그것을 테스트;) 및 mingw, 다른 OS/컴파일러를 사용하여 테스트 anuone? – Aname

+0

gcc 3.4로 시도해 보았습니다. 이클립스에서 Windows XP에서 cygwin을 사용하여 충돌하지 않습니다. 컴파일러 옵션도 중요합니다. -g를 넣으면 .i.e -O2 또는 다른 것을 사용하는 것과 다를 수 있습니다. 또한 제안 된 변경 사항을 시도했지만 충돌하지 않습니다. :) – Devolus

관련 문제