You're misunderstand what pointers are.
When you use pointers you have two things: the pointer itself, and the object pointed to. You can access the object pointed to by dereferencing the pointer (*pa). If you change the object, the change will be available to all pointers that point to that object. In this case, if you do *pa=4, then both *pa and *pb will equal 4; note that the dereference operator I'm using is very important to understand what I'm saying. Now, the pointers
themselves are nothing more than local variables, and pointers to the same location don't share their values (their values only
happen to be the same at some particular moment). If you do pa=0 (notice that there's no dereference there), you're making pa point to nowhere, but any other pointers that happened to have pa's previous value retain their value.
Now, your particular case.
On line 11 you're deleting pa. This doesn't delete
the pointer pa. It deletes the object (actually it's a variable, but object is a little more generic) pa points to. In other words, you're modifying what pa points to, so the change is shared by all pointer that are also pointing to that location.
On line 12 you're setting pa to NULL. You're not changing the object pointed to by pa (which at this point would be invalid, anyway), you're changing pa itself. pa is a local variable, so doing this affects pa, and pa alone.
On line 18 you're checking the value of pb, but since the change you made on line 12 didn't cascade to the other pointers, anything that happens from here is likely to cause the program to crash.
On line 21 you're deleting the object pointed to by pb. Since this object had already been deleted on line 11 (because pb still has the value pa had before line 12) and deleting an object twice is illegal, the program crashes.
About you second question
how can i know if the content pointed by pb available |
For example,
1 2 3 4 5
|
int *p=new int;
*p=45;
//here
delete p;
//here
|
It's impossible to know at lines 3 and 5 whether p points to an object that still exists. You can only tell whether a pointer is pointing to something by having it point to NULL or 0 (it's actually recommendable to make all invalid pointers point to 0, for reasons I can't remember at the moment), but you can't tell if a non-NULL and non-zero pointer is pointing to valid location.
This is why it's important to track ownership of pointers. A function owns a pointer if it's supposed to delete it after it's done with it. Likewise, an object owns a pointer if it's supposed to delete it when it's destructed. Needless to say, only one function or object should own the same pointer at any given time.
It's also important to make sure that all functions that know about the object are notified if it's deleted, but I can't think of any example where this is needed in non-threaded applications.
EDIT: I may seem to use the terms "pointer" and "object the pointer points to" interchangeably. "Pointer" is often used as a synonym for "address", specially when speaking about freeing memory. Whenever I talk about deleting a pointer, I'm talking about deleting the object at the address the pointer holds.