// allocating and deleting a pointer
#include <iostream>
usingnamespace std;
int main()
{
int localVariable = 5;
int * pLocal = &localVariable;
int * pHeap = newint;
if (pHeap == NULL)
{
cout <<"Error! No memory for pHeap!!";
return 1;
}
*pHeap = 7;
cout<<"Localvariable: " << localVariable << "\n";
cout<<"*pLocal: " << *pLocal <<"\n";
cout<<"*pHeap: " << *pHeap <<"\n";
delete pHeap;
if (pHeap == NULL)
{
cout<<"Error! No memory for pHeap!!";
return 1;
}
*pHeap = 9;
cout<< " *pHeap: " << *pHeap << "\n";
delete pHeap;
cin.get();
}
This code demonstrates the allocation of a pointer "on the heap" and the deletion of the memory stored at the pointer's address. However when I run the program, the CPU view of the program shows up. The program runs normally, but lags a load when I exit out.
Line 21: The condition will never be met. delete doesn't change the value of a pointer.
Line 26: Dereferencing an invalid pointer (made invalid by deleting it on line 20). This is illegal.
Line 28: Deleting a pointer that had already been deleted. Also illegal.
Lines 26 and 28 will normally crash a program. If they don't do it immediately, they'll leave the heap in an inconsistent state and the program will crash later on while allocating or freeing memory, usually very far from where the original error happened. These bugs are among the hardest you can possibly debug.
I took out the deletion at line 20 and the program works fine now. A question about how you said lines 26 and 28 will normally crash the program: in the program's current state (all of above except for line 20 taken out), would lines 26 and 28 still be a liability for a larger program, even though the dereference and deletion were made legal? I would assume not.
Also, so basically I have to give the pointer the value of NULL even after it's been deleted?
Also, so basically I have to give the pointer the value of NULL even after it's been deleted?
Depends. Usually not, but sometimes you do need to.
Suppose you have an array of pointers that you allocate and delete at random. Without using a separate array, there's no way to keep track of which elements are allocated and which aren't than by assigning zero/NULL to the ones that aren't.
Example of a case where you don't need to zero the pointer:
1 2 3 4 5 6 7 8 9 10 11
struct A{
T *a;
A(){
this->a=new T;
}
~A(){
deletethis->a;
//Zeroing is unnecessary:
//this->a=0;
}
};
The rule is: if there's a chance the pointer might be dereferenced after it's been deleted, zero it.
Okay. I'm still kind of new to pointers but it's getting easier. I think I understand it for the most part now. Thanks for your help helios, screw, Zhuge, and Warnis.
Line 11 will never be true. new will throw std::bad_alloc if no memory can be allocated, thus the throwing form of new will never return NULL.
Aside from the above reason, the check on line 20 is pointless because if pHeap were NULL, the program would have crashed on line 16, which would have been a dereference of a NULL pointer.