new/delete issue

Hi, all

I have a issue:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void main()
{
	
	int *pc = NULL;
	pc = new int(2);
	int *pa = pc;
	int *pb = pc;

	cout << *pa << endl << *pb << endl;

	delete pa;
	pa = NULL;
	if( pa )
	{
		cout << "*pa=" << *pa << endl;
	}

	if( pb )
	{
		//*pb = 20;
		delete pb; // crash here
		cout << "*pb=" << *pb << endl;
	}

	if( pc )
	{
		cout << "*pc=" << *pc << endl;
	}

	getchar();
}


the problem is : pa and pb both point to pc,

after I call delete pb; and set pb NULL;

if( pb ) still TRUE; and when delete it, crash.

how can i know if the content pointed by pb available, when code very complex.

Thanks,

Levi
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.
Last edited on
Right, excuse the ugliness of the construct below, but as Helios says if multiple pointers will be pointing to the same location, then when you delete & NULL one of them, it should happen to all of them, so something like...........also, my *[] precedence may be off and I'm too lazy to look it up...

[CODE]
void main()
{

int *pp[] = { 0, 0, 0, 0 };
pp[2] = new int(2);
pp[0] = pp[2];
pp[1] = pp[2];

cout << *pp[0] << endl << *pp[1] << endl;

delete pp[0];
pp[0] = pp[1] = pp[2] = NULL;
if( pp[0] )
{
cout << "*pa=" << *pp[0] << endl;
}

if( pp[1] )
{
//*pb = 20;
delete pp[1]; // crash here
pp[0] = pp[1] = pp[2] = NULL;
cout << "*pb=" << *pp[1] << endl;
}

if( pp[2] )
{
cout << "*pc=" << *pp[2] << endl;
}

getchar();
}
[CODE]
Topic archived. No new replies allowed.