Unclear about `delete` and pointers - c++

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).

Related

Identifying memory management issues

#include "A.h"
int main (int argc, char*argv[]){
A * p_a1 = new A();
A * p_a2 = p_a1;
delete p_a1;
p_a1 = 0;
delete p_a2 <br>
Could this code where A is some class lead to memory management issues?
My Thoughts:
The first line will create a pointer to A. I am not sure if this will allocate memory for A, too, or will it just assign an address? The second pointer p_a2 points to the exact location. delete p_a1 will delete the allocated memory, which probably didn't have anything p_a1=0, making it null. delete p_a2. We are then deleting the null pointer, which probably won't affect Could this lead to any memory leakage or issues?
Deleting the same object twice is definitely a memory management issue. delete p_a1; does delete the object pointed to by p_a1, then delete p_a2 tries to delete the very same object.
Remember: You are not deleting pointers, but you delete the object they are pointing to.
Raw new is always a code smell and a potential source of bugs. Your code should look like this instead:
#include "A.h"
int main (int argc, char*argv[]){
A a;
}
Frankly, given your question imho one can either only scratch the surface or write a long article to explain important basics. I opted for the first and refer you to a book for more details: The Definitive C++ Book Guide and List
Your problem is that p_a1 and p_a2 are independant pointers which at a time happen to point to the very same object.
After
delete p_a1;
p_a1 = 0;
all is fine from a p_a1 point of view: the object it pointed to has been deleted, and the pointer itself as received a nullptr value, so it is now safe to do delete p_a1 again.
But p_a2 has not been changed and now points to an object that has reached its end of life. So it has become a dangling pointer and dereferencing it or deleting it will invoke UB.
If you want p_a2 to be equivalent to p_a1 you should make it a reference:
A* &p_a2 = p_a1;
Now after p_a1 = 0, p_a2 is a reference to a null pointer and it can safely be deleted.

Why pointer is not NULL after using delete in C++

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.

c++ do I need to manually delete a void* pointer which is then pointing to another concrete type?

Assume I have a pointer void* p, then after some passing in and out of functions, let's say p is now pointing to int. Then do I need to manually delete as delete static_cast<int*>(p)?
In most places people say delete only happen when there is new. But in this case, it's not but does C++ itself remember to release that memory?
That all depends on how the int you're pointing to was allocated, you only delete what you new.
Correct (the int is new'd):
int* a = new int;
void* p = a;
//somewhere later...
delete static_cast<int*>(p);
Bad (the int is automatically managed):
int a = 0;
void* p = &a;
//somewhere later...
delete static_cast<int*>(p);
Answering the comment code, doing:
int* a = new int;
void* p = a;
delete p;
Is never okay. You should never delete through a void*, it's undefined behavior.
side note : in modern C++ you really shouldn't be using new or delete, stick with smart pointers or standard containers.
The short answer is: "It depends".
In most places people say delete only happen when there is new.
That's true so far as it goes. To avoid wasting resources and to ensure all destructors are called correctly every new has to be balanced by a delete somewhere. If your code can follow several paths you have to make sure that every path calls delete (if calling delete is appropriate).
The can get tricky when exceptions are thrown which is one reason why Modern C++ programmers generally avoid using new and delete. Instead they use the smart pointers std::unique_ptr and std::shared_ptr along with the helper template functions std::make_unique<T> and std::make_shared<T> (see the SO question: What is a smart pointer and when should I use one?) to implement a technique known as RAII (Resource Acquisition Is Instantiation).
But in this case, it's not …
Remember that the phrase ... when there is a new refers to the object the pointer points to not the pointer itself. Consider the following code...
int *a = new int();
void *p = a;
if (SomeTest())
{
delete a;
}
else
{
a = nullptr;
}
// This line is needed if SomeTest() returned false
// and undefined (dangerous) if SomeTest() returned true
delete static_cast<int *> (p);
Is that last line of code needed?
The object that a and p both point to was created by calling new so delete has to be called on something. If the function SomeTest() returned false then a has been set to nullptr so calling delete on it won't affect the object we created. Which means we do need that last line of code to properly delete the object that was newed up in the first line of code.
On the other hand, if the function SomeTest() returned true then we've already called delete for the object via the pointer a. In that case the last line of code is not needed and in fact may be dangerous.
The C++ standard says that calling delete on an object that has already been deleted results in "undefined behaviour" which means anything could happen. See the SO question: What happens in a double delete?
does C++ itself remember to release that memory?
Not for anything created by calling new. When you call new you are telling the compiler "I've got this, I will release that memory (by calling delete) when appropriate".
do I need to manually delete
Yes: if the object pointed to needs to be deleted here and the void * pointer is the only pointer you can use to delete the object.

Delete a pointer getting AccessViolationException

I have a class pointer declaration:
MyClass* a;
In destruction method I have:
if (a)
{
delete a;
a= NULL;
}
I got a problem when delete the pointer a:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What is the cause of the problem and how can I get rid of it?
With your current declaration:
MyClass* a;
a gets a random value. If you never give it a valid value later, such as:
a = new MyClass();
It will point to an unknown place in memory, quite probably not a memory area reserved for your program, and hence the error when you try to delete it.
The easiest way to avoid this problem is to give a a value when you declare it:
MyClass* a = new MyClass();
or, if you cannot give it a value when you declare it (maybe you don't know it yet), assign it to null:
MyClass* a = 0;
By the way, you can remove the test (if (a)) from your code. delete is a no-op on a null pointer.
Use smart pointer to free memory. delete in application code is always wrong.
unless you have initialized the pointer to something after this:
MyClass* a;
the pointer a will hold some random value. So your test
if (a) { }
will pass, and you attempt to delete some random memory location.
You can avoid this by initializing the pointer:
MyClass* a = 0;
Other options are that the object pointed to has been deleted elsewhere and the pointer not set to 0, or that it points to an object that is allocated on the stack.
As has been pointed out elsewhere, you could avoid all this trouble by using a smart pointer as opposed to a bare pointer in the first place. I would suggest having a look at std::unique_ptr.
How did you allocate the memory that a points to? If you used new[] (in order to create an array of MyClass), you must deallocate it with delete[] a;. If you allocated it with malloc() (which is probably a bad idea when working with classes), you must deallocate it with free().
If you allocated the memory with new, you have probably made a memory management error somewhere else - for instance, you might already have deallocated a, or you have written outside the bounds of some array. Try using Valgrind to debug memory problems.
You should use
MyClass* a = NULL;
in your declaration. If you never instantiate a, the pointer is pointing to an undefined region of memory. When the containing class destructor executes, it tries to delete that random location.
When you do MyClass* a; you declare a pointer without allocating any memory. You don't initialize it, and a is not necessarily NULL. So when you try to delete it, your test if (a) succeeds, but deallocation fails.
You should do MyClass* a = NULL; or MyClass* a(nullptr); if you can use C++11.
(I assume here you don't use new anywhere in this case, since you tell us that you only declare a pointer.)

Is this a memory leak?

char *pointer1;
char *pointer2;
pointer1 = new char[256];
pointer2 = pointer1;
delete [] pointer1;
In other words, do I have to do delete [] pointer2 as well?
Thanks!
Nope, that code is fine and won't leak memory.
You only have to use delete[] once because you've only used one new to allocate an area for memory, even though there are two pointers to that same memory.
A simple rule: you need as many deletes as there are news. Even better, use something like a smart pointer or a container to take care of it for you.
And another minor point: pointer2 is becoming a "dangling pointer" once you call delete on pointer1.
It's not a leak, but it is asking for trouble. pointer2 is pointing to who-knows-what as soon as you delete pointer1. It's what's called a "dangling pointer". Using it can in the best case cause a segfault, and in the worst case can cause mysterious data mangling in anything that ends up allocated that same spot.
While it doesn't leak memory, if you want to be explicit, you should set both point1 and point2 to NULL (and initialize them that way too.)
Additionally, consider using boost::shared_ptr<> from the Boost libraries. It's the greatest thing since sliced bread.
typedef boost::shared_ptr<TypeX> StrRef;
foo() {
StrRef pointer1(new TypeX);
while(something) {
StrRef pointer2 = pointer1;
// do stuff
}
return;
}
The data (TypeX) will be deleted when the last pointer to it goes out of scope. You can do something similar with the built-in auto_ptr<> type, if you don't need a reference count:
typedef auto_ptr<TypeX> StrRef;
foo() {
StrRef pointer1(new TypeX);
while(something) {
TypeX * pointer2 = pointer1.get();
subroutine(pointer2);
if (condition) return;
}
return;
}
Whenever pointer1 goes out of scope, it will delete the data. The advantage with this is that you don't have to remember put a delete before the return statement at the bottom, and if pointer1 goes out of scope for any other reason (i.e. return from the middle of the loop, or subroutine() throws an exception, then the data will still be deallocated properly.
I haven't tested this code, so you'll have to check the docs for auto_ptr<> and boost::shared_ptr<> yourself.
I highly recommend using the Boost libraries as much as possible. It's written by pro's it's basically a staging area for extensions to C++.
delete deletes the memory that was allocated by new. Since you only have one new you only need one delete.
Only use Delete when you've used New
Good practive is to set pointer2 to NULL, but you won't have a memory leak if you don't
Every new should have one, and only one, matching delete. If you deleted the other pointer, you would break that rule.
What you do here is just tell that memory block allocated by new char[256] would be pointed by pointer1 and pointer2 at the same moment.
It would be a memory leak if you wrote delete[] pointer2; statement after.
No, you do not have to delete[] pointer2 because you have not allocated memory for it!
The statement pointer2 = pointer1 makes pointer2 point to the same memory address as pointer1, does not allocate any extra memory for it.
Here's the gap in your thinking: You don't delete pointers — you delete memory. You simply use a pointer to identify the block of memory to be freed. Since the two variables point to the same memory, deleting one is precisely equivalent to deleting the other. In other words, deleting both is the same as deleting one of them twice — which is obviously wrong.