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.
Related
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.
I was implementing a LinkedList using C++, and I seem to have forgotten a few things when dealing with dynamically allocated memory.
I have a node class:
class Node {
public:
Node(int d) {
data = d;
next = NULL;
}
Node(int d, Node* n) {
data = d;
next = n;
}
int data;
Node* next;
};
and in my LinkedList class, I have the following method:
void remove(int n) {
Node* current;
current = head;
Node* previous = NULL;
while ( current->data != n && current->next != NULL) {
previous = current;
current = current->next;
}
if (current->data == n) {
previous->next = current->next;
current->next = NULL;
delete current;
}
else {
std::cout << "Node not found" << std::endl;
}
}
I seem to have forgotten..When I do delete current does that delete the Node ? Like the actual object that the pointer current points to? Or does it just delete the pointer? Or does the deletion of a pointer pointing to dynamically allocated memory using delete delete both the pointer and the object? Or do I need to have defined a Node class destructor for that?
It just deletes the struct -in your case node- it points to, you can still use that pointer -make it point to another node-, in fact there's no way delete the pointer itself since it's allocated on the stack. it's automatically "deleted" when you leave the function.
p.s: no need to set current->next to null
Delete just free's the memory pointed to. This has the following implications:
You are not allowed to access the memory at this location (use after free)
The amount of memory you needed for your Node object is free, meaning your program would use less RAM.
The pointer itself points either to a non-valid location or NULL, if you follow best practise and set it to NULL manually.
The data at the memory location where your object was can be overwritten by any other task that has a valid pointer on this location. So technically the Node data still remains in memory as long as nobody else overwrites it.
delete p causes the object pointed to by p to cease to exist. This means that
1, If the object has a destructor, it is called; and
2. p becomes an invalid pointer, so that any attempt to dereference it is undefined behaviour.
Generally, the memory occupied by said object becomes available to the program again, though this is really an implementation detail.
The phrase "delete the pointer" is normally a sloppy shorthand for "delete the object pointed-to by the pointer".
Assuming that you have allocated your object using new delete on a pointer does the following:
calls the destructor of the object
request that the memory is free ( when that happens is actually implementation dependent )
At some point the memory manager will free and mark it as non-accessible by the process.
Thus it is up to you to set the pointer after calling delete to an agreed value. The best practice it to set it as nullptr for the latest compilers.
It does delete the actual structure pointed to by current. Pointers remain intact. No need for defining destructor.
The delete operator is to be applied to pointer to object. The pointer is an address of memory on heap allocated by calling new. Internally there is just table of addresses allocated by new. So the key to free such memory is just that address. In your case such address is stored in variable of type pointer to Node named current.
There are few problems in your code. The problematic one is that you have no posibility to tell whether node stored in current is actually allocated on heap. It might happen that current node is allocated on stack. E.g.
void someFunction(LinkedList &list) {
Node myLocalNode(10);
list.add(&myLocalNode);
list.remove(10); //<-- disaster happens here
}
The same applies to statically allocated global variables.
You must take care of extreme cases. Think about what happens when deleted object is the first one, pointed by variable head. By deleteing its memory you end up with dangling pointer in head, pointing to either unallocated memory or memory used by someone else.
My third objection is to writing such structure at all. I hope it is just some school excercise, because in any other cases you should (almost must) use some existing list like std::list from C++ STL.
Whenever you call delete on a pointer variable, the object to which it is pointing to gets deleted from the memory, however the 4 bytes allocated to the actual pointer variable (in your case, the current variable), the 4 bytes will be freed only when the variable will go out of scope, ie At the end of the function
I have some issues about this code:
1) Why the output returns trash if I delete the first cell ?
int b = 1025;
char *v = new char[sizeof(int)];
memcpy(v,&b,sizeof(int));
char *pp = (char*)v;
++pp;
delete v; // is equal delete &v[0]
cout<<"salida"<<*pp;
2) How to delete dynamically allocated memory when i have void* ...
void *pv = v;
is correct
delete pv;
or
delete [](char*) pv;
i think what you are trying to do is deallocating the dynamically allocated memory..
first a pointer is always size of an int.
It only handles data locations(references).
A char pointer can store the address of a char type variable.
A void pointer can store the address of any data type.
so delete option works for both type of data types.
it simply deallocate the space and make it available on heap
A call to new[] needs to be matched by a call to delete[] on the same memory address and using the same pointer type.
A call to new needs to be matched by a call to delete on the same memory address and using the same pointer type.
If you mix things up, then you're invoking undefined behavior and will eventually have problems.
Maybe you'll occasionally be "lucky" and get away with it in certain simple circumstances because of how certain compilers have implemented dynamically allocated memory, but it's still a bad idea and could break at any time. If you try this with a class type which has a destructor, then one common consequence is that the destructor will not be properly run on some or all of the instances. But of course there are other possibilities, such as heap corruption.
So the result of a new char[] statement must be deallocated by a delete[] statement on a pointer of type char*.
You can't delete just one element of a dynamically-allocated array. If you allocate an array with new[], you can only delete the entire array, and you must use delete[], not delete.
Doing
char *v = new char[sizeof(int)];
and then
delete v;
invokes undefined behavior. You need to do delete[] v, and then you can no longer use pp because it points to something that's been deleted.
What exactly are you trying to delete, the char *v or void *pv?
If you want to delete char *v,
delete[] v;
v = NULL; // v still exists, but it's a dangling pointer now, so we set it to NULL (or 0)
Usually when you want to delete something, it has to be paired with new. So I think if you want to delete void *pv, you have to initialize the void pointer to new like this:
void** pv = new(void*); // Create a void pointer using new
pv = (char *)v;
delete pv;
I have a small homework problem.
The following code is given:
int * p;
p = new int;
*p = 5;
The question is: Why is it useless to do
p = 0;
delete p;
but usefull to do
delete p;
p = 0;
?
In my opinion, both is useless. If an object is deleted, no new value can be assigned.
I also get in both cases a Segmentation fault.
For Why it is useful for the following:
delete p;
p = 0;
Quoting from stroustrup's answer: Why doesn't delete zero out its operand?
Consider
delete p;
// ...
delete p;
If the ... part doesn't touch p then the second "delete p;" is a serious error that a C++ implementation cannot effectively protect itself against (without unusual precautions). Since deleting a zero pointer is harmless by definition, a simple solution would be for "delete p;" to do a "p=0;" after it has done whatever else is required.However, C++ doesn't guarantee that.
One reason is that the operand of delete need not be an lvalue. Consider:
delete p+1;
delete f(x);
Here, the implementation of delete does not have a pointer to which it can assign zero. These examples may be rare, but they do imply that it is not possible to guarantee that any pointer to a deleted object is 0.'' A simpler way of bypassing thatrule'' is to have two pointers to an object:
T* p = new T;
T* q = p;
delete p;
delete q; // ouch!
C++ explicitly allows an implementation of delete to zero out an lvalue operand, and I had hoped that implementations would do that, but that idea doesn't seem to have become popular with implementers.
If you consider zeroing out pointers important, consider using a destroy function:
template<class T> inline void destroy(T*& p) { delete p; p = 0; }
Consider this yet-another reason to minimize explicit use of new and delete by relying on standard library containers, handles, etc.
Note that passing the pointer as a reference (to allow the pointer to be zero'd out) has the added benefit of preventing destroy() from being called for an rvalue:
int* f();
int* p;
// ...
destroy(f()); // error: trying to pass an rvalue by non-const reference
destroy(p+1); // error: trying to pass an rvalue by non-const reference
Recall that deleting 0 is allowed. Therefore, when you do this
p = 0;
delete p; // Deleting zero is ignored
you throw away the old value of p (thus creating a memory leak), and then call delete 0, which is ignored.
When you do this, however
delete p;
p = 0;
you use the old value first (to de-allocate the int), and only then zero it out. This makes sense, because the old value of p becomes both useless and dangerous as soon as delete is executed.
This sets the pointer to null and then calls delete:
p = 0;
delete p;
It is like saying
delete 0;
I think what you are thinking is that it is setting the int that p points to to zero, but that would be done like this:
*p = 0;
p = NULL;
and
p = 0;
In the above case you are assigning value to the pointer and not to the object it points to.
Are one and the same. delete function is used to free the memory allocated dynamically to an object.
When you say
delete p;
p = 0;
It is like saying free the memory allocated to the pointer p and
then you are saying assign the pointer to NULL. Which is right.
In the other case when you do this
p = 0;
delete p;
You are saying assign the pointer to NULL first. Now the pointer p
is not pointing to any valid dynamically assigned memory. So later
when you say delete p the compiler cannot find any memory to free
and hence throws a segmentation fault.
In the first case, you are assigning the value of the POINTER p to be '0', not the value of the int that p points to. That's why it is both useless (will in fact cause a memory leak), and causes a seg fault when you try to delete from memory address '0'. EDIT - actually I just learned that the segfault is not caused by the 'delete 0', which is ignored according to the standard, so something else is causing that.
In the second case you are freeing the memory / object pointed to by p (which should be fine), and then assigning the pointer to have a value '0', which should also be Ok, so not sure why you are seg faulting there? In terms of usefulness, it used to be considered good practice to set free'd pointers to a null or '0' value so you can test for that before de-referencing them.
In C++, if you pass a pointer to a pointer into a method, do you delete the referenced pointer first? Do you have to clean it up within the method? I'm checking memory in task manager and it is leaking!
Thanks!!
You delete a pointer to a pointer like this:
int** p = 0;
p = new int*; // create first pointee
*p = new int; // create 2nd pointee
**p = 0; // assign 2nd pointee
// free everything
delete *p;
delete p;
It seems unusual to me to delete a pointer that was passed into a method. But anyways:
void freeme(int **p) {
delete *p;
*p = 0;
}
int main() {
int *a = new int;
*a = 3;
freeme(&a);
// a == 0 now
}
"A pointer to a pointer" ?
If for exemple you have :
MyClass * obj_ptr = new Myclass();
MyClass ** obj_ptr_ptr = &obj_ptr;
//then if you want to clean do :
delete (*obj_ptr_ptr);//to clean the class instance.
Why would you need to clean the pointer ... if you used malloc ... or any other dynamic (heap) allocation only.
But It's probably on the stack that you allocated the pointer so you don't need to clean it. At the end of his scope the memory on the stack used in the scope is cleaned.
You should start from the bottom, and go up. Otherwise, you will lose your reference to the data reference down the chain of references!
1. Delete the data you get by dereferencing twice, i.e. *myPtrToPtr
2. Delete the data you get (the pointer) by dereferencing once, i.e. myPtrToPtr
But of course, only do this if both the pointer and the thing it is pointing too have been dynamically allocated.
By I agree with the commenter... being more specific would be helpful to give us some context.
If it is leaking, you have to delete the referenced pointer first, then delete the referencing pointer. Once you delete the referencing pointer, accessing the storage of the referenced pointer would be undefined behaviour because you've just destroyed the object.
You first need to define who is the owner of each pointer before thinking about destroying it.
And if you have to destroy a pointer which points to a pointer you own, then you need to either destroy the referenced pointer first or save its value temporarily before destroying the other one.
But you should consider using a memory checking tool like valgrind/purify or equivalent and think about who is owning what (ie : who should destroy who) before doing wild guess.