If the ... part doesn't touch p then the second "delete p;" is a serious error that a C++ implementation cannot effectively protect itself against (without unusual precautions). Since deleting a zero pointer is harmless by definition, a simple solution would be for "delete p;" to do a "p=0;" after it has done whatever else is required. However, C++ doesn't guarantee that.
One reason is that the operand of delete need not be an lvalue. Consider:
delete p+1; delete f(x);
Here, the implementation of delete does not have a pointer to which it can assign zero. These examples may be rare, but they do imply that it is not possible to guarantee that ``any pointer to a deleted object is 0.'' A simpler way of bypassing that ``rule'' is to have two pointers to an object:
T* p = new T; T* q = p; delete p; delete q; // ouch!
C++ explicitly allows an implementation of delete to zero out an lvalue operand, and I had hoped that implementations would do that, but that idea doesn't seem to have become popular with implementers.
If you consider zeroing out pointers important, consider using a destroy function:
Consider this yet-another reason to minimize explicit use of new and delete by relying on stadard library containers, handles, etc.
Note that passing the pointer as a reference (to allow the pointer to be zero'd out) has the added benefit of preventing destroy() from being called for an rvalue:
int* f(); int* p; // ... destroy(f()); // error: trying to pass an rvalue by non-const reference destroy(p+1); // error: trying to pass an rvalue by non-const reference
虽然以下的代码我在GCC可以编译通过,并且可以运行,但是结果会导致未定义行为!!!
#include<iostream>
int main(int argc,char*argv[]) { std::cout<<"Hello, world"<<'\n';
int*i =newint(10);
std::cout<<i<<std::endl; delete i ; std::cout<<i<<std::endl; delete i ; return 0; }