I'm trying to understand how delete clears the memory allocated for an object.
Can anybody please explain it clearly?
I'm doing something like this:
class MyClass{
public :
MyClass() {std::cout <<" constructed\n";}
~MyClass() {std::cout <<" destroyed\n";}
};
int main ()
{
MyClass * pt=NULL;
pt = new MyClass();
delete pt;
if ( pt == NULL )
std::cout<<"deallocated\n";
}
delete pt will call the destructor ~MyClass(), then release any memory occupied by the object *pt back to the operating system.
What it doesn't do is change the value of the pointer, as that's unnecessary.
Some programmers will set pt = nullptr after a delete since the C++ standard guarantees that delete nullptr is a no-op. So it can help program stability.
delete p does indeed deallocate the storage occupied by the object pointed to by the value of p, among other things.
It does not modify the value of p, though. That wouldn't make sense. consider this:
int * funky_ptr();
delete funky_ptr();
Here the operand of delete is a prvalue; what sense would there be in modifying it?
It depends.
On debug builds, some compilers will usually clear out the memory (either set everything to 0 or some bit pattern that can be used to identity clears later) in order to help debugging.
That way, accessing a deleted object will more likely yield an access violation early on, rather than it failing silently.
On release builds, other than the (pseudo-)destructor being called, nothing else happens.
Note that setting pointers to NULL after delete or free is a code smell, as it can mask some bugs.
I'm trying to understand how delete clears the memory allocated for an object. can anybody please make it clear?
delete delete does the following:
look at the received address, and interpret it as a pointer (to data specified by the pointer type)
call the destructor(s) for all instances of data, for objects at the received address
tell the internal memory allocation subsystem, that the address in the received pointer, is now free. This will either release the memory to the operating system (so other applications can use it) or (more likely) cache it internally and use it for subsequent allocations (the next allocation performed using new or new[] with same or smaller size may receive this pointer).
These are the minimal steps to deallocate heap data in C++.
You will notice that nowhere in that list is a "set pointer to null/zero/speciffic value". This is because there are cases when the value of the pointer, is not interesting after the delete statement (such as, within a destructor body), and setting it to zero would just waste processor cycles.
As a rule of thumb, in C++ code is written so you do not pay for what you do not use. If you have use for such functionality, it is trivial to write it yourself (this example won't work for arrays):
template<typename T>
void safe_delete(T*& ptr) // use instead of delete
{
delete ptr;
ptr = nullptr;
}
Related
Say I have a pointer char* ptr allocated memory and another pointer char* arr = ptr
What happens to arr after ptr memory is deallocated.
Let the function be:
char* foo()
{
char* ptr = new char [100];
char* arr = ptr;
delete [] ptr;
return arr;
}
Can I use this returned value?
Will it cause any compile-time/Run-time error?
Or any thing else.
Or what would happen if the function was
char* foo()
{
char* ptr = new char [100];
char* arr = ptr;
delete [] arr;
return ptr;
}
I guess there would be no change from previous output but would there be any change??
What would happen If I have a class
class Pointer
{
public:
char* ptr;
Pointer()
{
ptr= new char [100];
}
~Pointer()
{
delete [] ptr;
}
};
and function
Pointer foo()
{
Pointer ptr;
ptr.ptr[0]='l';
return ptr;
}
Wont destructor be called at the end of the function and create a dangling pointer Pointer::ptr ??
Can I use this returned value??
You can "use" it, but you can't dereference it. You could, for example, print the pointer value out (but not the pointed-to data!):
std::cout << (intptr_t)foo() << std::endl; // OK
std::cout << foo(); // WRONG: this dereferences the pointer!
So while the value can be "used", it's not really useful as a pointer to char anymore.
Or what would happen if the function was [...]
Both functions have the same meaning. On any decent compiler, you should expect both to yield identical machine code when compiled.
What happens to arr after ptr memory is deallocated?
Nothing happens to it: its value remains unchanged. But because the pointed-to object has been deallocated, it is now a dangling pointer. So you can't use it for anything: if you do, you'll get undefined behavior. Undefined behavior means that anything can happen. This includes: nothing happening (things "appear" to "work OK"), or getting your hard drive formatted.
The situation is the same is if you built a house on a lot. You give your friend Arr the GPS coordinates. But in the meantime you decided to move out. Yet your friend Arr still has the old coordinates. Now Arr decides to use them. There are several possible outcomes - and you have no control over which one happens. I'll list just a few:
You moved out an hour ago. Everything is still the same. Arr stopped by, took a picture of your old home, and left.
This corresponds to a case where due to a coincidence, the pointed-to memory still contains usable contents. You still have a bug, but coincidence hides it.
You moved out, but the next day the city decided to raze the lot and build a big condo building on it and adjacent lots. Your friend comes in expecting a small house, sees a big condo high-rise and ends up completely stumped.
This corresponds to a case where the memory gets reused followed by the dangling pointer dereference. Whether this leads to CPU raising an exception or not depends on what kind of an object lived there before.
You moved out, but there was an earthquake and there's now a lake there. Your friend falls in and drowns.
This corresponds to a case where a now-redundant chunk of virtual memory that used to be a part of the free store has been unmapped. You get a page fault.
The memory manager runtime can deallocate the page that used to back the address space pointed to by your pointer. Recall that often a C++ program runs on top of a virtual memory machine. The address space seen by the program is the virtual address space. When there's no physical memory page backing a given virtual address space page, and no file or other backing for that page, any accesses to it will cause a page fault that propagates to userland and terminates the process if unhandled (as it is by default).
From your code the arr would point to not allocated memory so if you tried to work with it it would contain absolutely random data.
I once worked on an embedded system, and, as luck sometimes happens, I had the debugger connected near the correct place at the correct time (with respect to the delete) when the system crashed. The code was C++, the debugger was gdb, vxWorks is an embedded system tool suite.
The code I inspected was in some ways similar to your question, essentially a dereference of the pointer occurred after the delete.
...
char* ptr = new char [100];
delete [] ptr;
// more stuff that did not affect what ptr pointed to
// about 5 to 9 lines later
char retVal = ptr[x]; // <<< invalid access crash
...
The crash indicated that ptr[x] is invalid.
That embedded system (vxWorks) had techniques to confirm that where ptr pointed was indeed no longer in context, unmapped from that task.
I would guess it unusual (because of performance), but the delete not only released the block from dynamic memory, it also released the block of memory from the thread memory space, making the address invalid, causing a bus error.
I do not know how to confirm the similar information in Linux.
What happens to arr after ptr memory is deallocated?
The auto variables are unaffected by the delete.
Can I use this returned value?
Behavior is undefined (i.e. UB), so you should want to avoid doing so.
Will it cause any compile-time/Run-time error? Or any thing else.
UB means any thing else can happen.
I have the following below code snippet
class test{
private:
int *ptr;
public:
test(int *myptr){
ptr = myptr;
}
~test(){
delete ptr;
}
};
int main(){
int* myptr = new int;
*myptr = 10;
test obj(myptr);
delete myptr;
}
Is there a memory leak happening in this program, if I dont do a new to pointer in the class will space be allocated for that pointer?
Rule of thumb for dealing with allocating member: every new/new[] should be paired with exactly one delete/delete[]. If you are missing the delete, then you have a memory leak (you have allocated memory that you never clean up). If you are delete-ing multiples times, as you are doing in this code example, you will have memory corruption issues.
How are you delete-ing multiple times? In main(), you allocate a pointer:
int* myptr = new int;
You give a copy of that pointer to your test object, obj. Then, at the end of the scope we have:
{
// ...
delete myptr;
~test(); // implicit, which also does delete myptr
}
Only one of those two places should be responsible for delete-ing the pointer. Which one is based on the semantics of your code. Does test own the pointer? In which case, it should delete it but main() should not. Does it simply observe the pointer? In which case, it should not delete it. With C++11, we have new smart pointers to express this idea better.
I'd encourage you to browse the definitive C++ book list as concepts like this are very crucial to understanding C++ but also very difficult to explain properly in a short Q&A format.
You should only delte a pointer once in ~test() or delete directly
*** Error in `./a.out': double free or corruption (fasttop): 0x08d13a10 ***
Consider using std::shared_ptr<int> or std::unique_ptr<int>, since direct memory management is discouraged in modern C++ unless you've a reason to do so.
You can read about semantics differences of smart pointers here, and the reference for them is here.
It will crash when exit main function, a allocated in heap memory can't be release two times
What will happen in your instance is that the pointer will be given to delete in main(), then the same pointer value will be given a second time to delete in the destructor of obj. This is undefined behaviour, so it might work, or it might not, in any case, it isn't guaranteed to work, and therefore such a construct should not be used.
Ordinarily you would establish ownership rules, e.g. whether the constructor “takes ownership” (and is therefore responsible for freeing resources) is up to you, but typically, and especially in modern C++, ownership semantics can be clearly achieved by using std::unique_ptr and std::shared_ptr.
Most importantly, whichever method you use to determine ownership, make sure you are consistent! Avoid complicated ownership semantics, as it will make it much more difficult to detect memory-related issues (or more generally, resource-related issues).
Contrary to what other people have said: you do not delete pointers in C++, but objects.
What's the difference?
Let's simplify your code a bit:
int *myptr = new int; // 1
int *ptr = myptr; // 2
delete myptr; // 3
delete ptr; // 4
As far as the usage of new and delete is concerned, this is the same code - I've just removed the class, since it's not relevant to the point here.
This code does the following:
new int allocates an int, and returns its address. The address is then stored in myptr.
The address is copied to ptr. Both ptr and myptr contain the address of the int that was just allocated.
The int is deallocated.
The int is deallocated... but it was already deallocated? Oops!
If you're lucky, your program will crash at this point.
delete myptr; has nothing to do with the variable myptr, except that myptr holds the address of the thing to delete.
It doesn't even have to be a variable - you could do delete new int; (although it wouldn't be very useful) or delete someFunctionThatReturnsAnAddress();, or int *p = 1 + new int[2]; delete [] (p - 1);.
Your class has only a reference of the allocated integer. Consider to declare it int const* ptr, then you cant delete it inside the class.
You should remove delete ptr from the destructor.
Usually the scope which is allocating something is responsible for freeing it. In your case the main routine is allocating and has to free.
For your question "Is there a memory leak happening in this program", the answer is No, but an exception is rasing.
Your code logic is not good, you should delete the pointer at where it was created. In this example, you shouldn't delete ptr in destructor function.
Valgrind reports that my code (showed below) is causing a memory leak.
view *vi = new view(IPs);
initialView = *vi;
//delete vi;
So, I added delete. But deleting vi makes initialView empty!! And causes several problems to valgrind. What shall I do?
By the way, This is the equal operator of class view!
view & operator = (const view& v){
vp = std::vector <process>(v.vp);
return *this;
}
A pointer is assigned a memory location from the heap or free store when you use the new command. The thing is, after using this memory location through the pointer, the programmer has to explicitly de-allocate that memory block using the delete command. Otherwise, the program will run out of dynamic memory and crash. Basically, that's what a memory leak leads to.
When the delete pointer is used, it simply resets the value of pointer to null and makes the memory block free for re usage. All you have to do is delete the pointer you use AFTER its designated use.
for example:
for(int i=0;i<1000;i++)
{
int* ptr=new int;
*ptr=i;
cout<<*ptr; // ptr has been used, don't need it anymore
delete ptr; //if you don't use this, memory leak will occur
}
You can replace this raw pointer with shared_ptr if possible. It's based on reference counting and hence can take care of freeing the memory when no one is pointing to it.
From your code, it's hard to tell. Which static variables are you referring to in the title?
For valgrind to be happy, you of course have to delete vi. In your code, I can't see any dependencies between initialView and vi after the assignment - the vector constructor creates a copy of v's process list, and if those processes are not deleted with vi, this should be fine. If there are other dependencies causing you problems, try to eliminate them.
In a Visual C++ program, I am calling delete on a pointer. I will later need to check if the pointer has been deleted. I've noticed Visual C++ will set the address to 0x00000000, but later that value might be changed to something like 0xABABABAB, 0xFEEEFEEE, or some other value such as that. Checking for NULL only works on 0x00000000 addresses.
Is there a reliable way that I can check if the pointer was deleted, regardless of these changes the address may undergo?
If you are deleting a pointer to an object, you can see the destructor. If you want to know whether memory free operation was performed or not, there is no reliable/portable way to know this. Memory management is implementation dependant. Even this is possible that memory freeing is deferred by the library. But you should always believe that delete never fails. And if you have not overloaded delete operator, you can rely on libraries that memory would be released.
About memory contents, after contents being freed, you should not access them as the behaviour is undefined.
If you want this for debugging purpose, I would suggest using some alternate technique.
If you want to know whether pointer was freed, you should explicitly set it to 0, and you can later compare pointer with 0 to check whether it was freed.
if (...) {
delete ptr;
ptr = 0; // set explicitly
}
...
if(0 == ptr) {
// Pointer was freed
...
} else {
// Pointer was not freed
...
}
If you use C++11 you can just set the value of the pointer to nullptr and test for that afterwards (like if (foo == nullptr)).
int* f()
{
int *p = new int[10];
return p;
}
int main()
{
int *p = f();
//using p;
return 0;
}
Is it true that during stack destruction when function return it's value some compilers (common ones like VS or gcc were implied when I was told that) could try to automatically free memory pointed by local pointers such as p in this example? Even if it's not, would I be able to normally delete[] allocated memory in main? The problem seems to be that information about exact array size is lost at that point. Also, would the answer change in case of malloc and free?
Thank you.
Only Local variables are destroyed-released.
In your case p is "destroyed" (released) , but what what p points to, is not "destroyed" (released using delete[]).
Yes you can, and should/must use a delete[] on your main. But this does not imply using raw pointers in C++. You might find this e-book interesting : Link-Alf-Book
If you want to delete what a local variable points to when the function is "over" (out of scope) use std::auto_ptr() (only works for non-array variables though, not the ones which require delete[])
Also, would the answer change in case
of malloc and free?
Nope, but you should make sure that you do not mix free()/new/delete/malloc(). The same applies for new/delete[] and new[]/delete.
No, they won't free or delete what your pointer points to. They will only release the few bytes that the pointer itself occupies. A compiler that called free or delete would, I believe, violate the language standard.
You will only be able to delete[] memory in main if you a pointer to the memory, i.e., the result from f(). You don't need keep track of the size of the allocation; new and malloc do that for you, behind the scenes.
If you want memory cleaned up at function return, use a smart pointer such as boost::scoped_ptr or boost::scoped_array (both from the Boost collection of libraries), std::auto_ptr (in the current C++ standard, but about to be deprecated) or std::unique_ptr (in the upcoming standard).
In C, it's impossible to create a smart pointer.
Is it true that during stack destruction when function return it's value some compilers (common ones like VS or gcc were implied when I was told that) could try to automatically free memory pointed by local pointers such as p in this example?
Short Answer: No
Long Answer:
If you are using smart pointers or container (like you should be) then yes.
When the smart pointer goes out of scope the memory is released.
std::auto_ptr<int> f()
{
int *p = new int;
return p; // smart pointer credated here and returned.
// p should probably have been a smart pointer to start with
// But feeling lazy this morning.
}
std::vector<int> f1()
{
// If you want to allocate an array use a std::vector (or std::array from C++0x)
return std::vector<int>(10);
}
int main()
{
std::auto_ptr<int> p = f();
std::vector<int> p1 = f1();
//using p;
return 0; // p destroyed
}
Even if it's not, would I be able to normally delete[] allocated memory in main?
It is normal to make sure all memory is correctly freed as soon as you don't need it.
Note delete [] and delete are different so be careful about using them.
Memory allocated with new must be released with delete.
Memory allocated with new [] must be released with delete [].
Memory allocated with malloc/calloc/realloc must be released with free.
The problem seems to be that information about exact array size is lost at that point.
It is the runtime systems problem to remember this information. How it is stored it is not specified by the standard but usually it is close to the object that was allocated.
Also, would the answer change in case of malloc and free?
In C++ you should probably not use malloc/free. But they can be used. When they are used you should use them together to make sure that memory is not leaked.
You were misinformed - local variables are cleaned up, but the memory allocated to local pointers is not. If you weren't returning the pointer, you would have an immediate memory leak.
Don't worry about how the compiler keeps track of how many elements were allocated, it's an implementation detail that isn't addressed by the C++ standard. Just know that it works. (As long as you use the delete[] notation, which you did)
When you use new[] the compiler adds extra bookkeeping information so that it knows how many elements to delete[]. (In a similar way, when you use malloc it knows how many bytes to free. Some compiler libraries provide extensions to find out what that size is.)
I haven't heard of a compiler doing that, but it's certainly possible for a compiler to detect (in many cases) whether the allocated memory from the function isn't referenced by a pointer anymore, and then free that memory.
In your case however, the memory is not lost because you keep a pointer to it which is the return value of the function.
A very common case for memory leaks and a perfect candidate for such a feature would be this code:
int *f()
{
int *p = new int[10];
// do something that doesn't pass p to external
// functions or assign p to global data
return p;
}
int main()
{
while (1) {
f();
}
return 0;
}
As you can notice, the pointer to the allocated memory is lost and that can be detected by the compiler with absolute certainty.