Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pointer and dynamic memory allocation

Tags:

c++

pointers

My question:

int* x = new int;
cout << x<<"\n";
int* p;
cout << p <<"\n";
p = x;
delete p;
cout << p <<"\n";

I wrote this purely by myself to understand the pointer and to understand (also get lost in) the dynamic new and delete.

My XCode can compile the program and return the following results:

 0x100104250
 0x0
0x100104250

I know I can only call delete on dynamically allocated memory. However, I called delete on p in the above program and it compiles.

Could anyone explain this to me? Why could I delete p?

Moreover, I found if the program changes to the following:

 int* x = new int;
 int* p;
 cout << p <<"\n";
 delete p;
 cout << p <<"\n";

Then my Xcode again compiles and returns me:

 0x0
 0x0
 Program ended with exit code: 0

and now, I got completely lost:(. Could anyone please explain me this ? Why I could delete p since it has nothing to with x?


Since Xcode compiles successfully, I assume the above two programs are correct for computer. However, I think it is again the statement of "only call delete on dynamic allocated memory". Or probably, I didn't fully understand what is pointer and what is dynamic allocated memory. I found this post when I searched online. But I don't think it is like my case.

Please help me out.


I would like to ask one more question. The code is here about binary search tree. From line 28 to 32, it deals with deleting a node with one child. I put this part of code here, in case the weblink does not work.

else if(root->left == NULL) { struct Node *temp = root; root = root->right; delete temp; }

It is these codes leading me ask the above the question regarding pointer. Following the answer given by this post. Is it correct to understand the code in the following way?

I cannot firstly link the parent node of root to right child of root. and then delete the root node, as the subtree beneath the root node will also be deleted. So I must create a temp pointer, pointing to the memory slot, which is pointed to by root. Then I link the parent node of root to right child of root. and now, I can safely delete the memory slot pointed by "root", (i.e. temp as they both point to the same memory). In this way, I release the memory and also keep the link between parent and children. In addition, the temp is still there and still points to "that" memory slot. Should I set it to NULL after deletion?

Thank you all again in advance.

Yaofeng

like image 732
Bemtevi77 Avatar asked Sep 30 '22 06:09

Bemtevi77


2 Answers

Yes, you can only call delete on memory which was allocated via new. Notice that it's the address of the memory (the value of the pointer) which matters, and not the variable storing the pointer. So, your first code:

int* x = new int; //(A)
cout << x<<"\n";
int* p;
cout << p <<"\n";
p = x;  //(B)
delete p;  //(C)
cout << p <<"\n"; //(D)

Line (A) allocates memory dynamically at some address (0x100104250 in your example output) and stores this address in variable x. The memory is allocated via new, which means that delete must eventually be called on address 0x100104250.

Line (B) assigns the address 0x100104250 (value of pointer x) into the pointer p. Line (C) then calls delete p, which means "deallocate the memory pointed to by p." This means it calls delete on address 0x100104250, and all is well. The memory at address 0x100104250 was allocated via new, and so is not correctly allocated via delete. The fact that you used a different variable for storing the value plays no role.

Line (D) just prints out the value of the pointer. delete acts on the memory to which a pointer points, not on the pointer itself. The value of the pointer stays the same - it still points to the same memory, that memory is just no longer allocated.


The second example is different - you're calling delete p when p was not initialised to anything. It points to a random piece of memory, so calling delete on it is of course illegal (technically, it has "Undefined Behaviour", and will most likely crash).

It seems that in your particular example, you're running a debug build and your compiler is "helpfully" initialising local variables to 0 if you don't initialise them yourself. So it actually causes your second example to not crash, since calling delete on a null pointer is valid (and does nothing). But the program actually has a bug, since local variables are normally not initialised implicitly.

like image 63
Angew is no longer proud of SO Avatar answered Oct 05 '22 07:10

Angew is no longer proud of SO


p = x;

This would make p contain same value as x ( p would point to same object as x). So basically when you say

delete p;

Its doing delete on the address referred to by p which is same as that of x. Hence this is perfectly valid as object referred to by that address is allocated using new.

Second case :-

Co-incidently your pointer p is set by compiler as a NULL pointer( You should not depend on this). So deleting that pointer is safe. Had that not been a NULL pointer you would have possibly seen a crash.

like image 35
ravi Avatar answered Oct 05 '22 08:10

ravi