I am learning C++ in an online class, currently discussing pointers and memory leaks.
In the course it was told that when a function body ends all local variables are destroyed (in reverse order to which they were declared).
What i'm trying to understand is whether this code leaks memory or not:
void function()
{
TestClass *p = new TestClass();
}
As it seems, it does, but i am not sure why the pointer "p" is not being dereferenced to its heap address and the data there is deleted once the function scope exits.
Definitely it will leak memory. when a function body ends all local variables are destroyed indicates to the variables that are created in stack, not heap. If you allocate memory in heap, you have to release it when done.
Another thing is your concept about dereference is wrong. Dereference means using the object pointed by a pointer, not freeing the memory of the pointer, which is called Deallocation
The pointer itself will be destroyed as it is allocated in stack, but the data which p points to will leak. If you write
TestClass tc;
TestClass *p = &tc;
then all the objects will be created in stack and destroyed, but using new forces to use the memory from heap. You have to use delete to release it.
new is used to allocate memory for a C++ class object in heap, the object's constructor is called after the memory is allocated.
The delete operator must be used to deallocate the memory allocated with the new operator, otherwise there is a memory leak.
delete *p;
Related
Let consider this code:
#include <iostream>
class A{
public:
~A() {}
};
int main(){
A *p = new A();
p->~A();
return 0;
}
I would like to know if the memory of the object A pointed by p is freed or we must to call delete p;
The memory was not freed. The destructor destroys the object but does not free the memory. How could it? You can destroy objects that are dynamically allocated, are on the stack, are globals, and so on. The destructor has no idea what is needed, if anything, to release the memory.
Memory was allocated using operator new and will be freed (deallocated) using operator delete, not your object's destructor.
We should not confuse the object lifetime with dynamic memory management.
It is not A's destructor role to free the allocated memory and it should not be called explicitly. It is simply a member function that gets called when your object gets destroyed. And it will get destroyed after you call the delete.
Replace:
p->~A();
with:
delete p;
Now your objects gets destroyed and the allocated memory gets deallocated.
There is no difference between calling destructor or any other member function, except one thing - you should not do it, unless you want to separate object allocation from its construction and destruction.
MyClass* po = new MyClass();
po->DoSomething();
and
MyClass po;
MyClass* pp = &po;
pp->DoSomething();
can you explain this including what'll happen in the stack and the heap.
The first case is creating using dynamic memory allocation from the heap an instance of type MyClass. When you leave scope, the object pointed to po will still exist in the heap and leave a memory leak if not taken into account.
The second is instantiating an instance of MyClass on the stack. Then you create a pointer to type MyClass pointing to the object on the stack. When you leave scope, po will be destructed and the object pointed to by pp will be invalid.
The difference is the way you allocate memory.
MyClass* po = new MyClass(); allocates memory from heap and returns the pointer. You can access the memory using the given pointer.
MyClass po; allocates the memory on stack. After you leave the scope (when the function returns) you can't access this memory even if you had the pointer.
If I declare a struct such as this one:
struct MyStruct
{
int* nums;
};
MyStruct ms;
ms.nums = new int[4];
Do I need to call delete ms.nums; before exiting my program or will the member variable nums automatically get deallocated because the MyStruct instance ms wasn't declared on the heap?
Yes, you have to delete that.. struct's default destructor won't do that. It will just delete the pointer variable which holds the address of the object and object will be left alone forever.
Better to do the deletion inside the struct's destructor
struct MyStruct
{
int* nums;
public :
~MyStruct()
{
if(nums != NULL)
delete nums;
}
};
The member variable nums (which is a pointer) will get automatically deallocated when ms, the struct containing it, is popped off the stack.
However, the memory pointed to by nums will NOT. You should call delete [] ms.nums; before your program exits.
You always have to call delete to deallocate all the memory that you explicitly allocated using new.
When you allocate memory using new, memory is allocated in heap and the base address of the block is returned back.
Your struct is present in stack which contains a pointer pointing to that base address. When the struct object leaves the scope, the object is deallocated , i.e. the pointer containig the address of allocated heap memory block is gone, but the heap memory itself is still allocated which you can't deallocate now.
You need to call delete if memory allocated and pointer returned to num. Here num is a pointer inside a structure. Memory for num is allocated when you declare structure variable. But memory address which is allocated by new should be un-allocated by calling delete
Memory for the pointer itself will be deallocated when the object is destroyed, as it is for any class member. However, the array it points to won't be deleted - there is no way to know what the pointer points to, whether it was allocated by new or new[] or not dynamically allocated at all, or whether anything else still wants to use it. To avoid memory leaks, you should delete it, with the array form delete [] ms.nums;, once you've finished with it.
Since it's often hard to do this correctly, why not use a library class to manage the array correctly for you?
#include <vector>
struct MyStruct
{
std::vector<int> nums;
};
MyStruct ms;
ms.nums.resize(4);
Now all the memory will be released automatically when ms is destroyed; and the class is correctly copyable and (since C++11) efficiently movable.
The struct is allocated on the stack, which basically is a pointer to an Array. the array is allocated on the heap. Every time you write "new" that means that the allocation is on the heap therefore you need to "delete" it. On the other hand the struct will be remove as soon as you exit the function.
When program exit, OS will free all memory allocated by your program.
On the other hand, if a memory allocation occurs multiple times during the life of the program, then surely it should be released to prevent dangling pointers.
I've been experiencing segfaults when running some C++ code. I've isolated the problem to a line in the program that deletes a pointer. Here's a simple example that produces the same error:
int main()
{
int* pointer=0;
int number = 3;
pointer = &number;
delete pointer;//This line causes a segmentation fault
pointer=0;
return 0;
}
A slight modification produces code that will work as expected:
int main()
{
int* pointer=new int(3);
delete pointer;//This line now works
pointer=0;
return 0;
}
Can someone explain why the first causes a segfault and the second does not? I know the pointer isn't invalid, since it's been assigned to the address of the number variable.
You should only ever delete memory that has been allocated with new. Automatic variables declared on the stack do not need to be deleted. As a rule, always match your memory allocation and deallocation types:
Memory allocated with new should be deallocated with delete.
Memory allocated with new [] should be deallocated with delete [].
Memory allocated with malloc() should be deallocated with free().
The segfault is because the delete operator will attempt to put that memory back into the heap, and that relies on certain properties of the memory that don't hold true for automatic memory on the stack that didn't originate from the heap.
You can't use delete on anything you didn't get with new. Trying to do so will cause undefined behaviour. Your program crashed, but anything could have happened.
Calling delete on a pointer, deallocates the dynamically allocated memory that the pointer points to.
In the first program, pointer points to a statically allocated memory location.The variable number is an 'automatic' variable, which means that its memory is automatically managed.
On the other hand in the second program, pointer is pointing to a memory location allocated in the heap segment, which needs to be manually deallocated by calling delete.
You might find this link useful.
When you delete a pointer that wasn't allocated with new, you're creating a conflict between the memory management system and the stack. Each will operate as if it still has sole ownership of the memory, and a crash can result when they overwrite each other's values.
When you allocate a variabile with new:
int *a=new int(4);
This variable is put on the heap, which contains all the memory dnamicly allocated.
If instead you declare a variable:
int a=4;
a is allocated in the stack, where there is static memory.
Dynamic memory can be deallocated with delete from the user, but static memory can not.
Static memory is automaticlly deallocated when yuo exit froma function:
void function()
{
int a;
}
When the function ends a is automatically deallocated (except for variables declared with the keyword "static").
Also variables in main function are automatically deallocated.
So you can not say to the program to deallocate a variable in the stack.
In your example number is on the stack, pointer points to number which is in the stack, if you delete it you are trying to delete a variable in the stack, which is not allowed,because it's not dynamic memory.
I know from reading parashift.com that using delete on a pointer frees the memory
[16.1] Does delete p delete the pointer p, or the pointed-to-data *p?
The pointed-to-data.
The keyword should really be delete_the_thing_pointed_to_by. The same
abuse of English occurs when freeing the memory pointed to by a
pointer in C: free(p) really means free_the_stuff_pointed_to_by(p).
And the wiki article on "delete (C++)" says "many programmers set the pointer to NULL afterwards to minimize programming errors"
Is it necessary to think about deleting the pointer itself?
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
How would I delete the pointer?
Usually the pointer will stop existing at the end of the scope.
Example:
{
int *p = NULL;
// do something with p
} // <-- p will be destroyed here
Hereby the pointer variable is said to have automatic storage duration. If done consistently, assigning 0, or NULL, or nullptr to a pointer variable that doesn't point to an object of the specified type has the advantage that one can easily recognize whether or not it's safe to dereference the pointer. This practice has no direct connection to the lifetime of the pointer or the previously pointed to object (if any).
In contrast, when you have the following code:
{
int *p = new int;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
Again, the pointer variable itself will be destroyed at the end of the scope, because it has automatic storage duration.
In contrast, the int object, which we have allocated using the new operator, to which the pointer points in this example, has dynamic storage duration. It will continue to reside in memory until delete is called to free it. This may result in a memory leak (if you lose any reference to the object p pointed to, as in this example).
Of course, if the pointer is dynamically created by itself, e.g., as in
{
int** p = new int*;
// do something with p
//delete p; // <-- the object p points to will not be destroyed unless it's deleted
} // <-- p will be destroyed here
... this could be the starting point for a recursive example.
Note that there is a thing called static storage duration, which means the variable will exist until the end of the program (e.g., global or static variables). If you want to read up more on this topic see:
http://en.cppreference.com/w/cpp/language/storage_duration
http://en.cppreference.com/w/cpp/language/static
Note that independent of its storage duration, any variable (including pointers) takes up some amount of memory. Generally, if you allocate space for too many objects at the same time you will run out of memory. Therefore, you should avoid implementing things like infinite recursion, fork bombs, memory leaks, or alike.
Is it necessary to think about deleting the pointer itself?
It is only necessary if the pointer itself has no automatic memory management. That is, if storage for the pointer itself was allocated with new or malloc.
Is it correct to say that a declared pointer still takes up memory?
A pointer takes up memory, it has to be stored somewhere in order to be used, right?
if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
Of course it would use up memory, billions * sizeof(void*). Needing to delete the pointer has nothing to do with it taking space or not, everything takes space (well, almost, there are some special optimizations); you only need to delete what was allocated with new.
How would I delete the pointer?
How was it allocated? If it has automatic storage then its memory will be automatically freed when the pointer goes out of scope. If it was allocated with new it has to be deleted with delete, same for new[]/delete[] and malloc/free.
1) Usually a pointer is on the stack or a member of another class and you wouldn't need to worry about deleting such pointer.
2) Yes.
3) Yes, they would use up memory and you would need to release the pointer.
4) Either let a local pointer fall out of scope, or get rid of whichever object contains it.
Finally note that raw pointers are quite out of favor. Prefer either an appropriate container such as vector, or as needed an appropriate smart pointer.
A declared pointer takes up memory on the stack and will be deleted when it goes out of scope. This is the same process that takes place with primitive types. You do not need to worry about memory management for anything on the stack.
The new operator on the other hand allocates memory on the heap, and must be explicitly deleted with delete.
Is it necessary to think about deleting the pointer itself?
it depends on how the pointer was created. if you create a pointer on the stack:
void func(void) {
int* p;
...
}
you should delete the memory pointed to by p (when it makes sense), but p is simply an auto variable which will be "deleted" when the stack is unwind;
Is it correct to say that a declared pointer still takes up memory?
i.e. if I were to declare billions of different pointers to NULL, it would still use up memory (and hence I would have a need to delete the pointer itself).
of course it does... a pointer is just a location in memory containing an address into the virtual memory; in fact doubling the virtual memory space will double the space your pointers occupy (but not necessarily the space occupied by the data they point to).
How would I delete the pointer?
as I said, it depends on how you created the pointer. if you for some reason allocated it on the heap, then you should free that memory as well.
A pointer is simply a variable, like an int. On a 32-bit CPU a pointer will consume 4 bytes of storage, 8 bytes on a 64-bit system.
So if you declare a billion pointers to NULL, you have essentially declared a billion *int*s.
The thing that makes it a pointer is only the fact that the value stored in that variable just happens to be the address of some place in memory. When you call delete on a pointer, you are freeing the memory at that address stored in the pointer, not the memory used by the pointer variable itself.
You can not delete the pointer itself - only pointed by it data.
Pointer is destroyed when its scope is ended:
{
int *p = NULL;
}
After closing bracket the pointer is distroyed.
The question is what is deleting a pointer. If you assign new pointer to the same variable you don't need to worry about deleting billions. If you allocate space for pointer, you surely should delete them, but then again it will be pointer to pointers, so it's pointers, not pointer that is getting deleted. If you allocate space statically (like declaring array of billions of pointers) you can't really delete it.
In short, I think you need a better understanding of the nature of pointer.