2011-01-27 4 views
0

저는 C++을 배우는 중이며 삭제 연산자에 익숙하지 않습니다. 코드에서 볼 수 있듯이 새로운 연산자 (m)에 삭제 연산자를 적용하고 있습니다. 그것을 적용한 후에도 여전히 포인터를 사용하여 새로운 값을 할당 할 수 있습니다. 컴파일러 오류가 발생하지 않습니다. 내가 읽은 것부터, 포인터가 아무 것도 가리 키지 않기 때문에 delete를 적용한 후에 새로운 포인터를 사용할 수 없어야합니다. 어떤 도움도 환영합니다. 고맙습니다. 그것을 delete'ing 후 포인터를 사용하여 콘솔 OUPUTC++ - 연산자 삭제 혼동

14 12 
+2

아름다운 C++ 세계에 오신 것을 환영합니다. ; -> –

+0

포인터를 삭제 한 후에 포인터를 NULL로 수동 설정하는 것이 일반적으로 좋습니다 (tm). –

+4

누군가가 C++에서 뭔가를 할 수 없다고 말하면 컴파일러가 그럴 수는 없다는 것을 의미하지는 않습니다. "정의되지 않은 동작"(http : //en.wikipedia)을 초래하는 "오류"의 전체 범주가 있습니다.org/wiki/Undefined_behavior "undefined behavior") - 이것들은 컴파일러가시키는 일이지만 엉뚱하게 또는 기괴하게 행동하는 프로그램이 될 수 있습니다. –

답변

8

삭제 연산자가 약간 미묘합니다. 당신이

delete m; 

을 쓸 때이 코드의 의미는 "m가 가리키는 메모리를 회수"입니다. 즉 이 아니라이 포인터 m에 아무 것도하지 않고 오히려 m 점을 가리 킵니다. 예를 들어,이 그림에서 : 당신이 delete m을 작성하는 경우

 +-----+ 
m --> | 137 | 
     +-----+ 

포인터 m 값 137과 정수 가리키고, 다음 137을 잡고 메모리를 회수하지만, m 자체는 그대로입니다. 다른 개체 또는 NULL을 가리 키도록 다시 할당 할 수 있지만 더 이상 존재하지 않으므로 가리키는 데 사용한 값을 계속해서 참조하면 안됩니다.

0

int main() 
    { 
     int* m; 
     m = new int; 
     *m = 14; 
     cout << *m << " "; 
     delete m; 
     *m = 12; 
     cout << *m; 
    } 

는 "정의"입니다. 작동 할 수도 있습니다. 그렇지 않을 수도 있습니다. 거의 확실하게 (tm) 할 수있는 나쁜 일입니다.

2

컴파일러에서 확인하지 않습니다. 린트 같은 도구가 이것을 확인합니다. 네, 가끔은 삭제 된 메모리를 사용하여 도망 갈 수 있지만 정의되지 않은 동작입니다. 메모리는 더 이상 당신 소유가 아니므로 프로그램의 다른 객체가 사용중인 메모리를 쓰는 위험이 있습니다. 이는 프로그램이 너무 단순하기 때문에 발생하지 않습니다.

2

맞습니다. 코드가 잘못되었습니다.

delete m; 다음에 포인터 m은 유효한 int 변수를 더 이상 가리키지 않습니다. 따라서이 포인터를 역 참조 할 때마다 정의되지 않은 동작이 발생합니다. 프로그램이 예측할 수없는 방식으로 동작하여 버그를 일으킬 수 있습니다.

일부 컴파일러는 0xFEEEFEEE과 같은 특성 값이있는 "삭제 된"값 (포인터가 아님)을 작성하여 코드에서 그러한 오류를 찾는 데 도움이됩니다. 이렇게하면 디버깅 중에 삭제 된 메모리를 가리키는 포인터를 사용하려고한다는 사실을 알 수 있습니다.

1

delete m을 호출 한 후 m이 가리키는 메모리가 할당 해제되어 시스템에서 다시 할당 될 수 있습니다. 그러나 m은 여전히 ​​해당 위치를 가리 킵니다. 다시 말하면/dereference를 선택하면 일 수도 있고 원하는 값을 얻을 수 있습니다. 그렇지 않을 수도 있습니다. 정의되지 않은 동작입니다.