I wrote this and wondering why "deleted" isn't showing as output.
int *p=NULL;
p=new int(10);
cout<<*p<<endl;
delete p;
if(p==NULL)cout<<"deleted"<<endl;
Can Someone explain why it isn't printing after using delete and why delete isn't making the pointer NULL ?
It's because when you say delete p you're deleting a pointer to memory which completely erases the reference to the new memory you allocated. When you say if p==NULL you're checking to see if the pointer was set to null when in fact the memory that it was pointing to was de-allocated so the pointer isn't pointing to anything. Which doesn't mean the same as having it point to NULL in C++.
delete works on pointer values not pointer variables. For instance this is perfectly legal
int* some_func();
delete some_func();
As you can see there is no variable here and nothing to set to NULL.
Related
This looks simple question but my friend debated with me that below program invokes UB. But I think he is incorrect.
Consider following program:
#include <iostream>
int main()
{
int* p=new int[3]();
int* q=p;
for(int i=0;i<3;i++)
std::cout<<q[i]<<' ';
delete[] q;
std::cout<<'\n';
}
Is this program's behavior well defined? What happen if I write delete[] p; instead of delete[] q; ? Is it valid?
Yes the program is well defined. First you create a pointer assigned to newly allocated memory.
int* p=new int[3]();
Then you create another pointer pointing to that memory
int* q=p;
You then use that pointer to assign data into that memory. After that you delete memory which is pointer to q which is the same as p which is okay. The program returns and all is well
delete doesn't care about what variable you use. What is important is that the memory that the pointer points to was created with new and that you only call delete once on the memory.
The pointer returned by the new[] operator is not the start of the allocated memory but rather points to the first object (or the object at index 0). Now, based on the compiler you're using, the run-time system stores the number of objects, n, somewhere where it can be retrieved if you only know the memory location pointed by p.
According to this blog, the deletion of a vector performs this operation in reverse:
When you do "delete[] p", you are saying, "p points to a bunch of
objects, but I'm not telling you how many." In this case, the compiler
needs to generate extra code to keep track of how many it needs to
destruct. This extra information is kept in a "secret place" when the
vector is allocated with "new[]".
Since doing int *q = p essentially points to the same array's 0th object, it is equivalent to call delete[] q and delete[] p.
Operator delete can be applied ONLY to memory (i.e. address) that was allocated with operator new. If you allocate once you should free (detele) also once, does not metter which pointer (variable storing address) is used, so your code is valid.
But, remember, after you delete[] q neither q nor p DO NOT have to be used. The best way is assigne NULL to both pointers.
No UB. It will work fine. Not much to add here.
This the code:
char * asd = new char[10];
delete [] asd;
asd = new char[20];
Questions:
Doesn't the delete operation on pointers deletes the allocated memory being pointed to by the pointer?
is alright to reuse pointers after performing delete it on?
Doesn't the delete operation on pointers deletes the allocated memory
being pointed to by the pointer?
Yes.
is alright to reuse pointers after performing delete it on?
Yes, that's fine, as long as you set the pointer to the address of a different, valid object, which is what you are doing with your second invocation of new[].
Note that your question title "Reusing an array after deletion", is irrelevant to your question. You are not reusing an array that has been deleted, you are just reusing a pointer that used to point to an array which is now deleted.
If I remove a pointer to an object, what will be removed? Only the pointer or also the object which the pointer points to?
For example:
Assume I have a class with a variable
int *root
If I do the following in a method of that class
int *current = root;
delete current;
Will root also be deleted or only the pointer current?
I think you have a misconception about what delete does: delete deletes an object pointed to by a pointer that was previously allocated with new:
int* p = new int; // Create a new int and save its address in p
delete p; // Delete the int
Note that this does not delete p itself in any way, but only the object p points to! You can still use p like a normal variable, e.g. reassign it.
When you have multiple pointers to a pointee you only need to call delete on one of them.
int* root = new int;
int* current = root;
delete current;
std::cout << *root; // undefined behavior
The behavior of delete is described in ยง5.3.5:
6 If the value of the operand of the delete-expression is not a null
pointer value, the delete-expression will invoke the destructor (if
any) for the object or the elements of the array being deleted. In the
case of an array, the elements will be destroyed in order of
decreasing address (that is, in reverse order of the completion of
their constructor; see 12.6.2).
Yes, root is deleted, but depending of the compiler, current can still contain the address of an unexisting variable. So you have to do this to avoid mistakes :
delete current;
current = 0;
int *pointer = new int;
After this statement pointer would be pointing( pointer would be containing the address ) to a block of memory enough to store integer. What internally happens is some chunk from free store would be assigned allocated status.
When you execute
delete pointer;
That memory is returned back to free store so as to fulfill future needs. But you pointer would be containing the same address. When you execute delete again , it would led to undefined behavior since that block is already returned to free store ( that means you have lost the control over that memory through this pointer )
So, to be on safe side you generally set pointer to 0 after deleting that memory.
pointer = NULL;
In implementation of operator delete there is code which check if pointer is NULL, if it is then it returns. So, it's said that there's no harm in deleting NULL pointer.
I hope I have covered every basics.
Say we have a piece of code:
//...
class A
//...
A* myA = new A();
A* myPointerToMyA = myA;
delete myA;
delete myPointerToMyA; // this is wrong, no?
//...
The last line does the exact same thing as the one above it, correct? So I would now be deleteing an invalid/NULL pointer?
I understand this may be a stupid question, but still, I need some reassurance.
Indeed it is wrong. And in constrast to one of the other comments, it's not because you didn't allocate it with new.
Both myA and myPointerToMyA point at the same thing. Deleting through either of them is fine - but you can only delete it once legitimately because they point at the same thing - it is what is pointed at that is deleted, not the pointer itself.
There is nothing wrong with having two pointers to the same thing, but you musy keep track of who owns it, and who is responsible for deleting it.
In this instance, deleting a pointer to a deleted object, the behavior is 'undefined' - the run-time can do what it likes! (I can pretty much guarantee you won't like it...)
Yes, it's wrong. When you used delete, you're not deleting the pointer. Rather, you're deleting what it points to. So, when you use delete on a pointer, the memory that that pointer points to is freed. Any other pointer that points to that memory is now pointing to unallocated memory and is a dangling pointer. Using a dangling pointer results in undefined behavior, and it certainly isn't valid to try and free already freed memory, so using delete on a dangling pointer is definitely wrong. It will likely result in a segmentation fault.
You are correct.
So I would now be deleteing an invalid/NULL pointer?
Well, technically it's only invalid, because nothing was set to NULL. It's ok to delete a NULL pointer.
What you are getting here is the following:
A* myA = new A(); // myA is now equal to 0x11110000 for example(!)
A* myPointerToMyA = myA; // myPointerToMyA is now equal to 0x11110000
delete myA; // equal to delete (A*)(0x11110000)
delete myPointerToMyA; // equal to delete (A*)(0x11110000)
Two last lines are equal in the end. This code will lead to undefined behavior.
Yes it is wrong. The memory allocated for allocated with new A() and released with delete myA. One thing to note is that while delete myPointerToMyA is an attempt to delete an invalid pointer, it isn't an attempt to delete a NULL pointer because myPointerToMyA is not equal to NULL.
2 pointers point to the same object. The object gets destroyed after you call delete myA; for the first time. When you call delete for the second time(delete myPointerToMyA;) you are trying to delete object more than once, and the result of such action is undefined(usually you get runtime exception).
I have a pointer that points to an array and another pointer referencing the same array. How do i delete any one of those pointers without killing the array such that the second undeleted pointer still works?
for example:
int* pointer1 = new int [1000];
int* pointer2;
pointer2 = pointer1;
Now i want to get rid of pointer1, how would i do it such that i can continue to access the array normaly through pointer2?
Those pointers are on the stack; you don't have to delete them. Just ignore pointer1 and it will go away at the end of the block.
Let it go out of scope?
You don't 'delete' pointers, you delete what they point at. So if you just want to get rid of the variable 'pointer1' the only way to do that is for the scope it was created in to be terminated.
You don't pass that pointer to delete at all. You just stop using that pointer. If you want to make sure you don't access the array through that pointer again, you can set it to null.
C and C++ do not keep track of how many pointers point to an object or an array. If you want reference counting, you need to use a reference-counted container, like shared_ptr, or in this case, shared_array (you can find both of those in Boost and there is a high likelihood that your implementation already has them in <memory> either in the std namespace or in std::tr1).
When you statically declare a pointer with int* pointer1;, you can't free it. You can only free dynamically-allocated memory that you allocated using new, malloc, etc. The only way to "get rid of" pointer1 is to let it go out of scope, such as when the function returns. If you are done using pointer1 and want to prevent it from accidentally being used to alter the array, use pointer1 = NULL;.
Normally to make a pointer "safe" just set it to NULL which makes it point to nothing at all. Or you can just let it go out of scope.
For example, if you have two pointers.
int *a = new int;
int *b = a;
// somewhere
b = NULL;
delete b; // does nothing now
delete a; // deletes a
Or you can let it fall out of scope.
int *a = new int;
{
int *b = a;
// blah blah blah
}
// don't have to worry about b
delete a;
It's a stack variable (the way you've written it) and therefore bound to the scope you declared it in. Once you hit the closing curly brace of that particular scope, it will get cleaned up without you having to do anything about it.
If you want to make absolutely sure nothing else can use pointer1 any longer, you could set pointer1=NULL once you're done with it.
int** pointer1 = new int *;
* pointer1 = new int [1000];
int* pointer2;
pointer2 = * pointer1;
delete pointer1;
Just ignore the pointer, and it will go away when you're done with your function or block. Just remember that once you no longer have a pointer to something, it won't be able to be accessed. Of course, it will still be there using up memory, but you won't be able to get to it. So, before you consider letting go of the pointer, make sure you either have another pointer to it somewhere, or you get rid of it.