"이것을 삭제"한 후에 "이것" 값을 사용하면 안 되는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1866461

  •  18-09-2019
  •  | 
  •  

문제

~ 안에 C++ FAQ의 이 단락 사용법 delete this 구축이 논의된다.4가지 제한 사항이 나열되어 있습니다.

제한사항 1~3은 상당히 합리적으로 보입니다.그런데 "검사하거나, 다른 포인터와 비교하거나, NULL과 비교하거나, 인쇄하거나, 캐스팅하거나, 아무 작업도 수행해서는 안 된다"는 제한 4가 있는 이유는 무엇입니까?

내 말은 this 또 다른 포인터입니다.나는 왜 할 수 없습니까? reinterpret_cast 그것을 int 또는 전화 printf() 그 값을 출력하려면?

도움이 되었습니까?

해결책

삭제 한 후 포인터로 아무것도 할 수없는 이유 (이것 또는 다른 포인터)는 하드웨어가 유효하지 않은 메모리 주소를 레지스터에로드하려고 시도 할 수 있기 때문입니다. 모든 최신 하드웨어에서는 괜찮을지라도 표준은 유효하지 않은 포인터 (초기화 또는 삭제)에 할 수있는 유일한 일은 (NULL 또는 다른 유효한 포인터에서) 할당하는 것입니다.

다른 팁

Delete를 호출 한 후 'this'의 가치는 정의되지 않으며, 당신이하는 모든 일의 행동도 정의되지 않습니다. 대부분의 컴파일러가 현명한 일을 할 것으로 기대하지만,이 특정 경우의 동작이 하드 디스크를 형식화하기 위해 코드가 방출 될 것이라고 결정하지 못하게하는 것은 (사양에서) 아무것도 없습니다. 정의되지 않은 동작을 호출하는 것은 특정 컴파일러가 원하는 방식으로 작동하는 경우에도 항상 실수입니다.

Delete를 호출하기 전에 포인터 (정수)의 사본을 가져 와서이 문제를 해결할 수 있습니다.

아하!

3.7.3.2/4:"...할당 해제 기능은 포인터가 참조하는 저장소를 할당 해제하고 할당 해제된 저장소의 일부를 참조하는 모든 포인터를 무효화합니다.유효하지 않은 포인터 값을 사용한 결과(할당 해제 함수에 전달하는 것을 포함)는 정의되지 않습니다."

이는 "포인터 역참조"가 아니라 "값 사용"을 의미합니다.

해당 단락은 특정 항목에 국한되지 않습니다. this, 삭제된 모든 항목에 적용됩니다.

해당 포인터로 취할 수있는 모든 조치는 해당 객체의 클래스 방법에서 해석되는 논리를 트리거 할 수 있으므로 충돌로 이어질 수 있습니다.

이제, 당신이 지적하는 행동 중 일부는 분명히 "안전"할 수 있지만, 당신이 호출 할 수있는 모든 방법 내에서 어떤 일이 일어나는지 말하기는 어렵습니다.

게시물에서 : "검사해서는 안되며, 다른 포인터와 비교하고, 널과 비교하고, 인쇄하고, 캐스팅하고, 무엇이든해야합니다."

이러한 모든 작업은 연산자 관련 기능을 트리거 할 수 있으며, 이는 정의되지 않은 포인터로 평가됩니다. 캐스팅을위한 IDem.

이제 reintepret_cast를 수행한다면, 아마도 다른 이야기 일 것입니다. 그리고 당신은 아마도 다른 스토리 일 것입니다. 재 해석은 메소드 호출을 포함시키지 않고 약간의 재 해석이기 때문에 아마도 그것과 어울릴 수 있습니다.

같은 이유로 다른 포인터를 삭제하지 않은 다음 작업에 대한 작업을 수행하려고 시도합니다.

b/c 지금 말하는 주소는 정의되지 않았으며, 당신은 무엇이 있을지 모릅니다 ...

멀티 스레드 프로그램에서 순간 delete 포인터, 여유 공간은 다른 스레드에 의해 할당되어 사용 된 공간을 덮어 쓸 수 있습니다. this. 싱글 스레드 프로그램에서도 이전에 전화 한 것에 대해 매우 조심하지 않는 한 returning, 당신이 한 모든 일 delete this 메모리를 할당하고 사용했던 것을 덮어 쓸 수 있습니다. this.

디버그 모드에서 컴파일 된 Microsoft Visual C ++ 실행 가능 delete포인터를 사용하면 0xCC 테스트 패턴으로 메모리를 즉시 덮어 쓸 수 있습니다 (이 패턴으로도 초기화 된 변수도 초기화).

이것은 온라인 플레이 가능한 게임에서 버그를 수정했을 때 화재 물체의 생성자가 총 화재 수에 도달 한 경우 가장 오래된 화재를 삭제 한 것을 상기시켜줍니다. 삭제 된 화재는 때때로 부모의 화재로 새로운 화재를 일으켰습니다. BAM, 매달려 포인터 버그! 이 버그가 메모리 할당 알고리즘과 완전히 예측 가능한 방식으로 상호 작용 한 것은 행운 때문이었습니다 (삭제 된 화재는 항상 같은 방식으로 새로운 화재로 덮어 냈습니다). 게임이 메모리 할당 방식을 다시 작성할 때이 버그를 찾았습니다. 예측 가능성으로 인해 수정했을 때 오래된 게임 클라이언트와의 호환성에 대한 동작 에뮬레이션을 구현할 수있었습니다.

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