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.
Related
I'm new to the language and I have a basic doubt about memory leaks.
Is it possible to have a leak if I don't use the new keyword? (i.e having my variables in the stack and using data containers like std::vector)
Should I worry about this issue?
If that is the case, can someone give me an example of a situation that creates a leak without dynamically allocating memory?
i.e having my variables in the stack and using data containers like std::vector
No, with std::vector or other standard containers you shouldn't have to worry.
can someone give me an example of a situation that creates a leak without dynamically allocating memory?
One popular mistake are circularly dependent smart pointers of the form:
class Child;
class Parent {
std::vector<std::shared_ptr<Child>> childs;
};
class Child {
std::shared_ptr<Parent> parent;
};
Since the reference counters of the shared pointers will never drop to zero those instances never would be deleted and cause a memory leak.
More info about what causes that and how to avoid it can be found here
How to avoid memory leak with shared_ptr?
I think it is not possible to leak memory if you do not reserve memory dynamically. Probably, global variables are not going to be freed, but I would not call that a memory leak.
However, there are more ways to dynamically reserve memory than using the keyword new.
For example, malloc allocates a memory block. Also calloc reserves memory and zeroes it.
Your operating can also give you methods to manage the memory. For example strdup for Linux.
You can also be using smart pointers and calling std::make_unique or std::make_shared. Both methods dynamically allocate memory.
For std::unique_ptr you can leak if you call release() and forget to delete the pointer.
std::make_unique<int>(3).release(); // Memory leak
For std::shared_ptr you can leak if you create a circular reference. You can find more information here.
Also, when you use static variables, the destructor is not called when the variable goes out of scope but at the end of the execution. This is not exactly a memory leak because the destructor is finally called but you may have some memory allocated and not used.
For example, consider the following code:
#include <iostream>
#include <string>
#include <vector>
void f()
{
static std::vector<int> v;
v.insert(v.begin(), 100*1024*1024, 0);
v.clear();
}
int main()
{
f();
return 0;
}
std::vector::clear() is not required to free the memory allocated by the vector. So, after calling f(), you will have 400 MB of memory allocated but only accesible inside f(). Not exactly a memory leak, but it is a resource allocated that it is not automatically freed until the end.
In addition to the other answers, an easy source for memory leaks are external libraries. A lot of them, especially C or C-like libraries, have functions like create_* and destroy_* for their data types. Even though you never explicitly call new, it is still just as easy to have a memory leak.
which is better for memory allocation in c++ for classes and template. malloc() or new; can malloc() be used to allocate memory for classes or template?
It is possible to do this, although not the way you do it, and in any case it's not really beginner stuff. The reason your approach does not work is that an uninitialized slab of memory is not the same as a valid object. But before I continue:
IMPORTANT STYLE NOTE: I am going to leave aside for the sake of brevity the usual memory management mechanics (smart pointers et al) that you should stick to religiously as a beginner (and, in fact, as an expert, but they don't need to be told). Do not use code like what I'm about to show here in production (not without all the necessary bookkeeping around it), or things will break in ways that are horrible to debug. I'm only doing it because doing it properly would obscure the mechanics I'll try to show.
The difference between a slab of uninitialized memory and a valid object are, in a broad sense, class invariants. What this means is that a class defines certain properties for its objects that these always fulfill. For example, a string class will generally guarantee that the pointer to its data will not be a dangling pointer, and that its size will not reported to be larger than the block of memory that pointer points to. An uninitialized slab of memory cannot guarantee either of those things, and that is why we have constructors. A constructor is a function that constructs an object into an uninitialized slab of memory, fixing these invariants, and most of the time it is called for you automatically. If you write
Foo f;
memory is obtained from the stack (simplified terminology; please bear with me, language lawyers), and the default constructor Foo::Foo() is called on that piece of memory. Similarly, if you write
Foo *p = new Foo();
operator new obtains memory from the heap and calls the constructor on that piece of memory. Possibly it does more than that, but let's leave that possibility aside for now.
So what goes wrong in your code? Well, when you write
*obj = A();
this is an assignment. It assumes that there is a valid object *obj that a newly constructed object can be copied into. This is not the case, because obj points to an uninitialized slab of memory.
So, before you can use your uninitialized slab of memory like an object, you have to construct one into it. This is possible, and it is called placement new. The syntax looks like this:
new(obj) A();
And later you have to call the destructor (the constructor's counterpart; its purpose is to undo what the constructor did) manually like so:
obj->~A();
...after which obj will again point to uninitialized memory, and (unless the class is buggy) all necessary cleanup has been done. Except giving back the slab of memory, because that was allocated outside the constructor/destructor duo. Normally it would happen automatically at the end of the scope (for automatic variables like f above) or delete would do it for you (for dynamic storage objects like *p above), but since you did the allocation yourself, you have to do the deallocation yourself.
The use of malloc() for allocatiog C++ objects shall be avoided.
Rewrite your main() using C++ practice:
A *obj = new A(); // get memory and initialize the object
B<int> *objb = new B<int>(); // same
This works better and is easier to read !
Remark: Statements like *obj=A(); may call a class specific assignment operator, which would assume that *obj was already initialized by a constructor and is in a valid state. If memory was simply aquired by malloc(), this assumption is not fulfilled.
I'm using numerous vectors in a program and I want to avoid memory leaks. Here is an example of a vector containing classes I have created myself.
vector<MyClass> objects;
objects = vector<MyClass>(10);
As you can see, I haven't used the "new" operator and the vector is not of a pointer type. Will I still encounter memory leaks without deleting the vector in some way? If so, how can I delete the vector and deallocate the memory?
No, you won't encounter directly a memory leaks related to the vector this way. Indeed, objects is a variable with automatic storage duration. What this means is that the variable you created will live in the scope you created it. If you've created it in a function, and if/for/while/etc scope or even a raw block scope, it will be cleaned up at the end of this same scope, without the need for any actions from your part.
Then, nothing is preventing your class itself from leaking, e.g. if you have ownership of some memory and don't release it as an instance of your class go away.
A memory leak is defined as memory that exists, but you don't have access to anymore because you lost the pointer. Do this in a loop and you will be out of available memory real quick.
If you don't use new to allocate memory dynamically, you cannot have a memory leak.
Lets assume you add instances to this vector in a loop. This consumes a lot of memory. But it's not a leak, because you know exactly where your memory went. And you can still release it if no longer needed.
From the vector docs it would appear that the proper way to completely deallocate a vector of values to which you have a class member pointer such as:
std::vector<MyObject>* mvMyObjectVector_ptr;
...
//In the class constructor:
mvMyObjectVector_ptr = new std::vector<MyObject>();
would be to invoke the following, in order, in the class's destructor implementation
mvMyObjectVector_ptr->clear();
delete mvMyObjectVector_ptr;
However, this appears to be leading to SIGABRT 'pointer being freed was not allocated' errors. Is the above idiom the correct way to completely deallocate the memory held at the address pointed to by a pointer to a vector (if it is, I assume my errors are coming from something else)? If not, what is the correct way?
Yes, it is correct, provided mvMyObjectVector_ptr has been allocated using new.
Additionally, MyObject needs to satisfy certain requirements before it can be used with std::vector.
The call to clear() is redundant and can be omitted.
Some likely reasons for the SIGABRT include:
mvMyObjectVector_ptr hasn't been allocated using new;
MyObject violates the Rule of Three;
the class the contains the vector violates the Rule of Three.
I don' think your problem lies in the code you have shown us.
This line:
//In the class constructor:
suggests you are using this inside a class and not implementing the rule of three correctly.
A better idea is not to use a pointer to a vector.
Just declare it as a normal automatic member.
class MyClassContainingVector
{
public:
std::vector<MyObject> mvMyObjectVector;
// ^^^^^ notice no pointer.
};
Now it will be created and destroyed correctly and automatically.
Neither your constructor or destructor will need any code to manage this object.
Yes, dynamically allocating a std::vector object by calling new and invoking its destruction by calling delete will result in memory that has been internally used for holding its elements being freed.
However it would be much simpler and more reliable to follow RAII idiom and use an object with automatic storage duration:
{
std::vector<MyObject> myVector;
...
} // <-- memory is freed here
when execution leaves this scope (note that it could be also caused by exception being thrown etc.), it is guaranteed that myVector object will be destructed and memory will be freed.
Vectors usually shouldn't be held as dynamically allocated pointers. They should be just member variables of your class, in most situations (though there are always exceptions). If they are pointers allocated by 'new', and simple 'delete' should work.
Vectors handle memory allocation for you, so you don't have to. However, if you want to truly free all the storage memory held in a vector, even if it's on the stack, there's a new function for that.
Because vector.reserve() only expands memory, but never shrinks it, in C++11, a new function was added for the purpose of freeing the reserved memory: vector.shrink_to_fit(). Implementations and free to do what they want with it, but you're basically asking the implementation to free the memory, so they should answer the request in a reasonable way.
You can truly clear a vector by going like this:
vector.clear(); //Erases the elements.
vector.shrink_to_fit(); //Erases the memory no longer needed by the elements.
The reasons why vectors hold onto their memory is for performance reasons, so you should only do this if you actually understand why they have memory in reserve, and are willing to deal with (or know you won't have to deal with) any performance hits that result from micro-managing the memory.
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.