It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I just know the formal meaning of memory leaking where if we do not use the keyword 'delete' for deleting pointers. But when we perform in the following way why is there a chance of leak?
void k()
{
vector<m*>p;
:
:
:
}
as far as i know the deletion of the pointers is done automatically by the compiler itself, so is it really necessary that we delete pointers at the end?
This depends on what you put into p. If you just store pointers to something managed elsewhere (or to something not allocated dynamically), there is no leak: the contents of the vector will be cleaned up by its destructor.
However, if you do something like p.push_back(new m);, and never call delete on the elements of p before k exits, then you're indeed leaking memory. The contents of the vector (the pointers) will be cleaned up by its destructor; the memory the pointer point to will not.
as far as i know the deletion of the pointers is done automatically by the compiler itself
No, it's not. The following is a leak:
vector<m*>p;
p.push_back(new m);
You'd need to delete the memory yourself:
delete p[0]; //in this case
The clean alternative is using smart pointers:
vector<std::shared_ptr<m> > p;
Assuming you allocate the contents of the vector (the m*s ) with new you WILL need to perform delete yourself before you exit the function, if you want to avoid leak. The automatic deletion of vector contents works well only if the content is a object, not pointer to a dynamically allocated object.
What you can do is replace m* with std::unique_ptr<m>. Now the smart pointer will automatically perform delete and you dont need to do anything.
vector<std::unique_ptr<m>>p;
Alternatively, this is also safe. Since you are storing by value, the contents will be automatically destroyed by the vectors destructor when it leaves the function.
vector<m>p;
Just to address your initial question: There are two related, but distinct notions of memory management errors. I like the terminology used by Valgrind, a popular memory debugger:
Still reachable memory: This is not strictly a leak, but rather just laziness on part of the programmer. It's unclean, but not necessarily a problem. This happens when you just don't bother to clean something up that you could have cleaned up:
int main()
{
int * p = new int[100];
}
// memory at p is still reachable
In such code the "still reachable" allocation is typically in use until the end of the program, and the only sensible point at which to clean up would be at the very end.
Definitely lost memory: This is your real leak. This situation occurs when you lose all references to dynamically allocated memory. That means that you have no way, even in principle, to ever release those resources. This is a serious programming error. If you leak memory in a loop, or in something that is called an arbitrary number of times, your program may very well just die after it's been running for too long, possibly not before making the rest of the OS unusable for a while. Typical code looks like this:
int foo()
{
int * p = new int[100]();
return p[20] + 2;
} // leak: We lost track of the memory at p
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
int * q = new int[line.length() + 1];
q[0] = foo(); // leak 1
} // leak 2: lost track of the memory at q
}
All of the above situations violate the fundamental rule of memory management, formulated first in the 13th century:
CPU, make me an instrument of your code.
Where there is malloc, let me write free.
Where there is new, delete.
Where there is new[], delete[].
Enter
As a corollary, we can deduce the Golden Rule of C++ memory management, which reduces the risk of memory management bugs dramatically:
Don't use new and never use delete. Don't use raw pointers.
The point is that raw pointers don't carry any ownership information about the possible pointee. Thus it is impossible based on a raw pointer alone to decide whether and how any cleaning up may need to be done. This is also the problem with your code -- the answer is simply, "it depends"!
The vector itself is fine. It'll manage its own memory automatically and correctly.
The answer therefore depends on what you put in that vector. If you put pointers to heap-allocated objects, it is your responsibility to deallocate those objects when you're done with them. The vector won't do that for you.
If you fail to do that, you'll have a memory leak.
When you remove elements from that vector (using resize, erase or clear), and assuming that m* is allocated with new, it will NOT use the delete operator. Therefore you will have a memory leak. However if those pointers point to a variable on the stack, there will be no memory leak.
EDIT:
You can delete elements before you erase elements from the vector, however if you do a call to resize or clear, you will more than likely not delete all of them (unless you loop and delete before you clear).
The pointers in the vector are not deleted when the vector is deleted. You may use
vector<shared_ptr<m>> p
if you share the pointers with other parts of your program.
A superficial answer is no: you haven't allocated any memory in
your snippet, so there can be no leak.
A more usable answer would be: it depends on what the role of
the vector is, and what you are putting in it.
For starters, if the type m has value semantics, and is
copyable, you should be using vector<m>, and not vector<m*>.
And of course, there's no chance of a leak with vector<m>
(assuming that you've implemented m correctly).
The most frequent reason for using a vector of pointers, at
least in the application domains I've worked in, is for
navigation between entity objects. Each entity object manages
its own lifetime, or (less frequently), belongs to some other
entity object which will manage its lifetime. So there's no
risk of a leak, but there is a very significant risk of
a dangling pointer: when the lifetime of a pointed to object
ends, you have to ensure that any pointer to it is removed from
the vector. (This is usually done by using some variant of the
observer pattern.)
Another reason for using a vector of pointers is that the
contained objects are polymorphic, or large and expensive to
copy. In such cases, if the contained objects contain no
pointers, or you can otherwise prove that cycles would be
impossible, and the pointed to objects don't have significant
internal behavior (so there is only very limited use of this),
you could make a collection of std::shared_ptr<m>; in
practice, Boost's pointer containers are probably a better
solution (and avoid the risks of std::shared_ptr). Both the
shared_ptr solution and Boost's pointer containers require
that all elements in the vector be dynamically allocated.
Related
Is there any way to distinguish two following situations at run time:
double ptr * = new double(3.14159);
double variable = 3.14159
double * testPtr_1 = ptr;
double * testPtr_2 = &variable;
delete testPtr_1 // fine...
delete testPtr_2 // BIG RUN TIME ERROR !!!
I have find myself in situation in with I need to call delete operator for some unknown pointer. The pointer can point to anywhere (to a "local" variable or to dynamically allocated variable).
How can I find out where my "unknown" pointer points, and therefore choose when to and when not to call operator delete on it
EDIT:
Ok I see that everyone is pointing me to the smart pointers, but what if I am trying to write my own set of smart pointers (that is The reason behind my question)?
There is no way to test if a pointer is pointing to a memory area that would be valid to delete. Moreover,
There is no way to tell between pointers that must be freed with delete vs. delete[],
There is no way to tell between the pointers that have been freed and pointers that have not been freed,
There is no way to tell among pointers to an automatic variable, pointers to static variable, and pointers to dynamically allocated blocks.
The approach that you should take is tracking allocations/deallocations by some other means, such as storing flags along with your pointers. However, this is rather tedious: a much better practice is to switch to smart pointers, which would track resources for you.
You need to set some better coding practices for yourself (or for your project).
Especially since most platforms have, at the very least, a C++11-compliant compiler, there's no reason not to be using the following paradigm:
Raw Pointers (T*) should ONLY be used as non-owning pointers. If you receive a T* as the input for a function or constructor, you should assume you have no responsibility for deleting it. If you have an instance or local variable that is a T*, you should assume you have no responsibility for deleting it.
Unique Pointers (std::unique_ptr<T>) should be used as single-ownership pointers, and in general, these should be your default go-to choice for any situation where you need to dynamically allocate memory. std::make_unique<T>() should be preferred for creating any kind of Unique Pointer, as this prevents you from ever seeing the raw pointer in use, and it prevents issues like you described in your original post.
Shared Pointers (std::shared_ptr<T> and std::weak_ptr<T>) should ONLY be used in situations where it is logically correct to have multiple owners of an object. These situations occur less often than you think, by the way! std::make_shared<T>() is the preferred method of creating Shared Pointers, for the same reasons as std::make_unique, and also because std::make_shared can perform some optimizations on the allocations, improving performance.
Vectors (std::vector<T>) should be used in situations where you need to allocate multiple objects into heap space, the same as if you called new T[size]. There's no reason to use pointers at all except in very exotic situations.
It should go without saying that you need to take my rules of "ONLY do 'x'" with a grain of salt: Occasionally, you will have to break those rules, and you might be in a situation where you need a different set of rules. But for 99% of use-cases, those rules are correct and will best convey the semantics you need to prevent memory leaks and properly reason about the behavior of your code.
You cannot.
Avoid raw pointers and use smart pointers, particularly std::unique_ptr. It conveys clearly who is responsible for deleting the object, and the object will be deleted when the std::unique_ptr goes out of scope.
When creating objects, avoid using new. Wrap them in a smart pointer directly and do not take addresses of anything to wrap it in a smart pointer. This way, all raw pointers will never need freeing and all smart pointers will get cleaned up properly when their time has come.
Okay, some things you can distinguish in a very platform-specific, implementation-defined manner. I won’t go into details here, because it’s essentially insane to do (and, again, depends on the platform and implementation), but you are asking for it.
Distinguish local, global and heap variables. This is actually possible on many modern architectures, simply because those three are different ranges of the address space. Global variables live in the data section (as defined by the linker and run-time loader), local variables on the stack (usually at the end of the address space) and heap variables live in memory obtained during run-time (usually not at the end of the address space and of course not overlapping the data and code sections, a.k.a. "mostly everything else"). The memory allocator knows which range that is and can tell you details about the blocks in there, see below.
Detect already-freed variables: you can ask the memory allocator that, possibly by inspecting its state. You can even find out when a pointer points into a allocated region and then find out the block to which it belongs. This is however probably computationally expensive to do.
Distinguishing heap and stack is a bit tricky. If your stack grows large and your program is running long and some piece of heap has been returned to the OS, it is possible that an address which formerly belonged to the heap now belongs to the stack (and the opposite may be possible too). So as I mentioned, it is insane to do this.
You can't reliably. This is why owning raw pointers are dangerous, they do not couple the lifetime to the pointer but instead leave it up to you the programmers to know all the things that could happen and prepare for them all.
This is why we have smart pointers now. These pointers couple the life time to the pointer which means the pointer is only deleted once it is no longer in use anywhere. This makes dealing with pointer much more manageable.
The cpp core guildlines suggests that a raw pointer should never be deleted as it is just a view. You are just using it like a reference and it's lifetime is managed by something else.
Ok I see that everyone is pointing me to the smart pointers, but what if I am trying to write my own set of smart pointers (that is The reason behind my question)?
In that case do like the standard smart pointers do and take a deleter which you default to just using delete. That way if the user of the class wants to pass in a pointer to a stack object they can specify a do nothing deleter and you smart pointer will use that and, well, do nothing. This puts the onus on the person using the smart pointer to tell the pointer how to delete what it points to. Normally they will never need to use something other than the default but if they happen to use a custom allocator and need to use a custom deallocator they can do so using this method.
Actually you can. But memory overhead occurs.
You overload new and delete operator and then keep track of allocations and store it somewhere(void *)
#include<iostream>
#include<algorithm>
using namespace std;
void** memoryTrack=(void **)malloc(sizeof(void *)*100); //This will store address of newly allocated memory by new operator(really malloc)
int cnt=0;//just to count
//New operator overloaded
void *operator new( size_t stAllocateBlock ) {
cout<<"in new";
void *ptr = malloc(stAllocateBlock); //Allocate memory using malloc
memoryTrack[cnt] = ptr;//Store it in our memoryTrack
cnt++; //Increment counter
return ptr; //return address generated by malloc
}
void display()
{
for(int i=0;i<cnt;i++)
cout<<memoryTrack[i]<<endl;
}
int main()
{
double *ptr = new double(3.14159);
double variable = 3.14159;
double * testPtr_1 = ptr;
double * testPtr_2 = &variable;
delete testPtr_1; // fine...
delete testPtr_2;
return 0;
}
Now the most important function(You will have to work on this because it is not complete)
void operator delete( void *pvMem )
{
//Just printing the address to be searched in our memoryTrack
cout<<pvMem<<endl;
//If found free the memory
if(find(memoryTrack,memoryTrack+cnt,pvMem)!=memoryTrack+cnt)
{
//cout<<*(find(memoryTrack,memoryTrack+cnt,pvMem));
cout<<"Can be deleted\n";
free (pvMem);
//After this make that location of memoryTrack as NULL
//Also keep track of indices that are NULL
//So that you can insert next address there
//Or better yet implement linked list(Sorry was too lazy to do)
}
else
cout<<"Don't delete memory that was not allocated by you\n";
}
Output
in new
0xde1360
0xde1360
Can be deleted
0xde1360
0x7ffe4fa33f08
Dont delete memory that was not allocated by you
0xde1360
Important Node
This is just basics and just code to get you started
Open for others to edit and make necessary changes/optimization
Cannot use STL, they use new operator(if some can implement them please do,it would help to reduce and optimize the code)
I'm wondering if RAII always allocates on the stack, or if the compiler ever uses the heap for large objects (and then perhaps adds a token to the stack as a sort of reminder of when to destroy the corresponding heap-allocated object)?
UPDATE: Apparently this question has been deemed unclear. Perhaps a code example will make this clearer:
In this code:
void dosomething() {
MyClass myclass();
}
Assuming the compiler didn't optimize away such a trivial example, does the instance of MyClass that's hereby created always get allocated on the stack, or is the heap ever used?
I think I understand the answer now thanks to the accepted answer -- the answer appears to be that the class instance itself goes on the stack while its contents may or may not depending on how its constructor was defined. Please add a comment/answer if this is incorrect.
The way you talk about RAII makes it sound like you have something of a mis-impression about the most fundamental idea of what RAII is. RAII (also known as SBRM--stack bound resource management, so no RAII isn't really entirely orthogonal to at least the concept of a stack) is basically a style of programming.
Programs written using RAII can and often do allocate memory from the free store. Such allocations, however, are handled by an object of some class. When the object is destroyed, the class' destructor executes, and that frees the dynamically allocated memory.
Just for example, a typical string object will only contain a small amount of data, such as a pointer to the string's contents and an integer or two to keep track of the string size. When you create the string, it'll allocate some space from the free store to hold the actual data. When the string is destroyed, it'll automatically free that data. In some cases, it'll have some logic to avoid that free store allocation for small strings by allocating some small (fixed) amount of space in the string object itself, but doesn't change the basic idea.
So, the real answer is a qualified "yes". Yes, it's fairly common to have a small object that contains a pointer to some data allocated on the heap. Yes, the object will free that memory when the object itself is destroyed. But no, that's not something the compiler does for you. Rather, it's something you do in designing and implementing your classes.
so i would like to have vector<OtherClassName> theVector as a member of a BaseClass
i am wondering in many ways that i can get a memory leaks...
will doing this results in memory leaks?
BaseClass::someFunction(){
OtherClassName * c = new OtherClassName();
theVector.push_back((*c));
}
i'm a beginner in C++, learning from the internet.
will doing this result in memory leaks?
Yes, this will result in a memory leak. Every object allocated with new must be destroyed with delete. Failing to do so causes a memory leak.
In particular, what you are storing in your vector here is a copy of the object allocated with new. If you want your container to hold objects of a certain class, it is enough to do:
BaseClass::someFunction()
{
OtherClassName c;
theVector.push_back(c);
}
Notice that the vector, like all containers of the C++ Standard library, has value semantics: this means that what you are inserting in the vector is a copy of the object you pass to push_back(). Further modifications to the original objects won't be reflected by the state of the object contained in the vector, and vice versa.
If you want this to happen, i.e. if you need reference semantics, you will have to let your vector contain (possibly smart) pointers. For instance:
#include <memory>
// theVector would be declared as:
// std::vector<std::shared_ptr<OtherClassName>> theVector;
BaseClass::someFunction()
{
std::shared_ptr<OtherClassName> pC = std::make_shared<OtherClassName>();
theVector.push_back(pC);
}
Manual memory management through new and delete is considered bad programming practice in Modern C++, because it easily leads to memory leaks or undefined behavior, and negatively affects the design of your program in terms of robustness, readability, and ease of maintenance.
Classes that dynamically create anything should have a destructor that will free the memory when the object is destroyed. If you don't have one you have memory leaks. Any memory taken by a new statement must have a corresponding delete statement or you will have a memory leak. As your class is written now it will have memory leaks since you never free the memory again. Your destructor should simply go through the vector and free the memory from every pointer it stores.
So here is the problem I am having.
I have a pointer to std::vector. So after I initialize the pointer, I don't add any items to the vector, nor remove any. However, at a certain point in my code, my std::vector moves locations, and I end up with a dangling pointer. This seems to happen randomly, even though I never touch the vector after making the pointer
It took me a while debugging this, to figure this problem out. Is there a way to guarantee that my std::vector will not change memory locations? Or is it just a bad idea to have a pointer to a vector.
Or is it just a bad idea to have a pointer to a vector?
In general, I would say it is a bad idea to have raw pointers for controlling an object's lifetime. Don't use raw pointers and automatic memory management, try using smart pointers with the appropriate ownership semantics (std::shared_ptr<> or std::unique_ptr<>). Use raw pointers only for observing pointers (and if you want to be able to verify at run-time whether they are dangling, use weak_ptr<>).
Also, in many cases you may realize you do not need a pointer at all. In that case, just use an object with automatic storage, which can be efficiently moved around or passed/returned by value in C++11 thanks to move semantics.
This seems to happen randomly
No, it doesn't. As long as it stays in scope it has the same address. What is probably happening is that the vector is going out of scope, and since it was automatically allocated (sounds like) it is getting destroyed at that time. What you can do is allocate the vector on the heap (for e.g. ints):
std::vector<int>* pv = new std::vector<int>();
Then you will not have this problem. However you must remember to explicitly delete it with
delete vp;
before pv goes out of scope or you'll get a memory leak.
I've painfully learned during last few days a lot about programming in c++.
I love it :)
I know I should release memory - the golden "each malloc=free" or "each new=delete" rules exist now in my world, but I'm using them to rather simple objects.
What about vector ? Wherever I can, I'm using vector.clear() but that clearly isn't enough, because I'm having huge memory leaks.
Could you guide me on how should I treat this thing?
*Edit
Thanks, your comments made me think about the alghorithm of this application and I'll be able to eliminate the vector totally. :O
Sorry - I started explaining what is my use case here and I found out what I really need. It's like that when you code last 3 days for 18 hours a day :|
*Edit 2
This is crazy. By small changes in code, I've eliminated memory usage from 2x130 mb (constantly growing) into 2x 13,5mb, constant size. Thanks for making me think about that in another way.
Btw. such self code review got a name - anyone remember that? It's when you ask anyone (even your mother or dog) and start explaining what's your problem - and suddenly you solve this 5 hour problem yourself, just by trying to look at it from other point of view, or just by trying to summarize what's it all about. I often find myself being catched on that...
The rule is that when you clear a vector of objects, the destructor of each element will be called. On the other hand, if you have a vector of pointers, vector::clear() will not call delete on them, and you have to delete them yourself.
So if all you have is a vector of strings, and not pointers to strings, then your memory leaks must be caused by something else.
You don't need to be doing this. std::string cleans itself up, so the strings are not your problem. Remember that YOU didn't use new so YOU don't have to use delete.
You should probably learn about RAII - it makes allocation and deallocation much simpler. You'll avoid memory leaks this way.
Calling v.clear() will destroy all objects that are currently held inside v, but it will not release the memory (it is assumed that the vector will soon be filled again).
If you really want to free the memory, the idiom is
vector<string>().swap(v);
This will create a new (temporary) vector and swap its contents with v. The temporary vector is then destroyed, freeing the memory along with it.
Deleting elements from STL containers is guaranteed to call destructors on these elements.
However, if you have a container of some pointer-to-T type, then you still have to free the pointed-to memory yourself (in this case, the "destructor" for the pointer gets called, which is a no-operation).
If you do not want to manually manage memory in this case, consider using a smart-pointer solution or a pointer container.
The vector (like all standard containers) owns the objects inside it.
So it is responsible for destroying them.
Note: If you vector contains pointers then it owns the pointers (not what the pointers point at). So these need to be deleted. But there are easier ways.
You could use a vector of smart pointers. In fact you should be using some form of smart pointer for nearly everything. If you are using pointers you are probably still programming like a C programmer.
So:
std::vector<int> data; // clear is fine.
std::vector<int*> data1; // Now things need to be deleted.
// alternative 1:
std::vector<boost::shared_ptr<int> > data2; // The shared pointer will auto
// delete the pointer.
// alternative 2:
boost::ptr_vector<int> data3; // Here the container knows that
// it is holding pointers and will
// auto de-reference them when you
// its members.
But it sounds like you need to start thinking about learning about smart pointers.
int* x = new int(5);
// Do stuff.
*x = 8;
delete x;
// --- Instead use a smart pointer:
std::auto_ptr<int> x(new int(5));
// Do stuff.
*x = 8;
// No delete (the auto ptr handles it.
If you have a vector and it goes out of scope, all objects in the vector are destroyed. There isn't really a need to call clear() unless you want to dump the contents and reuse the vector.
However if you by any chance are using something like a vector then the destructor of the objects being pointed to will not be called as the vector destructor doesn't follow the indirections represented by the pointers.
All that said, have you actually confirmed that you've got genuine memory leaks and that they are caused by the data in the vector?
Give a use case. The destructor on the string is getting called by vector::clear. Your problem lies elsewhere my friend.
also check out:
Does std::vector.clear() do delete (free memory) on each element?
As rlbond suggested, use RAII.
It's a good rule of thumb to never put new and delete calls into your main code flow. Always try to put them into objects so that the object destructor can free what needs to be freed. In this way, you avoid needing to remember to call delete and it makes your code exception safe (assuming that you make your object's operations exception safe).
For example, if you had a vector of pointers to STL strings or C-style character arrays, put that into a StringContainer (use a better name) and have the StringContainer hold a vector and in the StringContainer destructor run a for loop to delete each string in the vector.
You can make the vector inside the StringContainer a public member and mess around with it directly, but it's even better design to make it private or protected and add some member functions to manage the string* vector.
So your main C++ program should never see a new or delete anywhere. Instead it should have a lot of stack allocated objects, auto_ptrs and shared_ptrs.