How to delete a pointer to a pointer? - c++

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.

Related

Why cant set pointers in functions

I have noticed that if i create a pointer in a function, it won't let me set a value to it.
for example:
int func() {
int* pointer;
*pointer = 0 //error I get: "Exception: STATUS_ACCESS_VIOLATION"
return *pointer;
}
I get that not letting you set a pointer in the function because if I use a normal int it works:
int func() {
int notAPointer;
notAPointer = 0;
return notAPointer;
}
Can anyone explain to me why that is?
You haven't assigned any memory for your pointer to point to.
That means that dereferencing the pointer (*pointer) causes undefined behavior (like a crash in your case). You need to initialize the pointer before dereferencing it:
int* pointer = new int;
(And afterwards, delete pointer; to not leak the memory. Always delete everything you get from new.)
Also, pointers don't have to point to dynamically allocated data (acquired by a call to new), you can point to automatic (stack) variables too:
int func() {
int valueOnStack = 42;
int* pointer = &valueOnStack;
*pointer = 0;
return *pointer;
}
Because when you declare pointer it is pointing to a completely arbitrary memory location. You can't just write to any old piece of memory.
You need to allocate memory for it first:
int* pointer = new int;
*pointer = 0;
Or just:
int* pointer = new int();
The pointer pointer is uninitialized and points to a random location in memory when you declare it. It could be pointing into the system stack, or the global variables, or into the program's code space, or into the operating system. When you say *pointer = 0;, the program will simply try to write a 0 to whatever random location pointer points to.
The program may explode immediately, or may wait half an hour and then explode, or it may subtly corrupt data in another part of your program and you may never realize it. This can make this error very hard to track down. Make sure you initialize all pointers to a valid address before dereferencing them.
pointer does not point to anything following int* pointer;
So the behaviour of dereferencing it is undefined.
If you'd written
int n;
pointer = &n;
then you could dereference it.
Altenatively, you can allocate memory to it from the heap:
pointer = new int;
But you must remember to call delete pointer; else you'll leak memory.
This code is completely valid inside a function:
int *pointer = 0;
BUT, it would be the same as setting a pointer to the NULL macro.
If you try to set another value the compiler is going to complain that there is no valid conversion from int to int*:
int *pointer = 1; // Error
However, if you want to assign a value to the pointer, follow TartanLlama's answer using new and delete. Allocate memory first and then assign a value:
int *pointer = new int;
*pointer = 1; // OK
// delete when appropriate

What will get removed if i remove a pointer in c++

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.

C++ delete problems dynamically allocated memory

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;

Assign value to deleted object

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.

How do you delete a pointer without deleting the data the pointer points to?

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.