So, basically, your problem with the first version is that, while it sets the local pointer p
to be NULL, the pointer in the calling code isn't automatically set to NULL, and so could accidentally be used to try and access memory that is no longer valid? Is that correct?
If I've understood you correctly, that's a valid criticism, and your proposed second version fixes that.
A more elegant version would be to pass in a reference to the pointer:
void workWithPointer(MyType*& p)
//do some stuff with p
delete p; //this deletes de pointer
p = NULL;
The comments you've written on line 4 in each of your versions don't make much sense. In both cases, line 4 deletes the object that the pointer is pointing to. Nothing deletes the pointer itself, in either version. The only difference between the two is in whether the new value of the pointer (NULL) is passed back to the calling code.
I suspect you've misunderstood something about pointers and/or dynamic memory management, but I'm not sure what, exactly.