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.
Related
I wanted to ask, is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
for example:
int main()
{
int c = 50;
// Memory leak
int * q = new int;
q = & c;
delete q;
}
What exactly is getting deleted or happening?
Thanks!
What exactly is getting deleted or happening?
Memory leaking and undefined behaviour.
When you do q = & c; you are losing your only tracking of the memory allocated by new int. Noone keeps track of this for you, there is no garbage collector, it is simply lost and cannot be recovered.
When you then do delete q; (where q is assigned to &c) you are deleting memory that you didn't allocate, and worse you are deleting memory on the stack. Either of these will result in undefined behavior.
This is an excellent preface into why you should avoid using pointers in circumstances where you don't need them. In this case, there is no reason dynamically allocate your int. If you really need a pointer, use a c++11 smart pointer (or boost if you don't have c++11). There are increasingly rare cases where you really do need a raw c type pointer. You should read Effective Modern c++ Chapter 4 for excellent detail on this subject.
is dynamically creating a pointer, and then changing a pointer address to something else still deleting the original allocated space?
No. delete will deallocate the memory to which its operand points. You must delete the same block of memory that you obtained from new.
int c = 50;
int * q = new int;
int * r = q;
q = & c;
delete q; // WRONG! q points to something you didn't get from new
delete r; // OK! p points to the block you got from new
To be even more clear, delete doesn't care about what variable it operates on, it only cares about what that variable points to. In the last line above, r points to the block that was originally pointed to by q and allocated by new, so you can safely delete it. q points to statically allocated memory, not something you got from new, so you can't delete it.
Instead of changing where q points, though, you can copy the value you want into the space that q points to:
int c = 50;
int * q = new int;
*q = c;
delete q; // OK! q still points to the same place
Here you're changing the value stored in the location to which q points, but you're not changing q itself. q still points to the block you got from new, so it's safe to delete it.
You code will (try to) delete c. There's no memory management or anything like that in C/C++. delete will try to delete whatever the given pointer points to, and and whatever is not deleted (either by calling delete for variables created with a call to new, or by leaving the scope for local variables) will remain in memory until the program ends.
Notice that trying to delete a local variable will propably cause a crash, since delete actually checks (in a very basic manner) what it deletes - at least to know how much memory has actually been allocated at that address. And at this check, it will propably notice that c doesn't include this information, or that it isn't even at the right end of the memory space, so it will crash.
It will crash because c is created in the stack memory section. If you're lucky and the program didn't crash you aren still leaking memory because the q reference is lost.
First answer is to your question:-
I wanted to ask, is dynamically creating a pointer
We don't create a pointer dynamically. Pointers are just a variable like other variable in C and C++. Difference is, pointer is a variable which can store the address of a particular memory location. In run time you just dynamically allocate memory and assign the address of first address location of that memory size into it.
Now what will happen if you don't delete/free the memory and assign a new address to it. In that case memory will not be release/freed and that can not be use anymore as that will never be marked as free by OS. When you free/delete memory O/S mark that area as free to use, and your running process can utilize it in future. That is call proper memory management. Improper memory manage leads your program to memory leak.
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.
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;
}
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 the following C++ code a memory leak?
list.push_back(new String("hi"));
As I understand it, push_back from any std collection/container always makes a copy. So if the new string is copied, nothing can ever delete the new'd string right? since there is no reference to it after the push_back...
Am I correct or wrong here?
Thanks.
Jbu
edit: I think I am wrong, since new will return a pointer...we'll always have the pointer to be able to delete the new String
Yes, but not for the reason you think.
Depending on how list is defined and initialized, push_back might throw an exception. If it does, the pointer returned from new is lost, and can never be freed.
But assuming push_back returns successfully, it stores a copy of the pointer returned by new, and so we can free the memory later by calling delete on that copy, so no memory is leaked as long as you do call delete properly.
No, the vector stores pointers and the copy is made of the pointer. You can delete the object any time later.
(You may get a leak, if the statement happens to throw an exception and you don't catch and handle it properly. That's why you might consider using smart pointers.)
If I saw this code I would be very suspicious a memory leak was possible. On the surface it appears to be adding an allocated String* into a list<String*>. In my experience this is often followed by bad error handling code which does not properly free the allocated memory.
While this dangerous in many circumstances it is not necessarily a memory leak. Consider the following example:
class Container {
~Container() {
std::list<String*>::iterator it = list.begin();
while (it != list.end()) {
delete *it;
it++;
}
}
void SomeMethod() {
...
list.push_back(new String("hi"));
}
std::list<String*> list;
}
In this code there is no leak because the containing class is responsible for the memory allocated and will free it in the destructor.
EDIT
As aschepler pointed out there is still a leak if the push_back method throws an exception.
You are correct, provided nothing deletes the string when it is removed from the list.
Yes, this is a memory leak unles you somehow take steps to delete the contained pointers.
And the best way to accomplish that is to use a smart pointer. For example, Boost's shared_ptr or C++0x's shared_ptr.
list.push_back(new String("hi"));
Why are you allocating dynamic strings in the first place? Unless you want to communicate between different parts of your program by changing strings (which would be quite unusual), get rid of the pointer:
std::list<std::string> list; // note: no pointer!
list.push_back(std::string("hi")); // explicitly create temporary
list.push_back("hi"); // alternative: rely on coercion
No.
You can delete the object by doing:
delete list[i];
list.erase(list.begin() + i);
or clear the whole list by:
for (unsigned int i = 0; i < list.size(); ++i)
{
delete list[i];
}
list.clear();