Is dynamic memory destroyed when static object is destroyed? - c++

Taking a look to the following code snippet:
//A.h
class A
{
void f();
};
//A.cpp
#include "A.h"
void A:f()
{
map<string, string> *ThisMap = new map<string, string>;
//more code (a delete will not appear)
}
//main.cpp
#include "A.h"
int main( int argc, char **argv )
{
A object;
object.f();
//more code (a delete will not appear)
return 0;
}
When main() ends it execution, object will be destroyed. Would be destroyed dinamic allocated memory asigned to ThisMap too?

Would be destroyed dinamic allocated memory asigned to ThisMap too?
No!
You have a memory leak, since object gets destroyed, its destructor gets called, but no delete is called for your map.
Pro-tip: delete whatever you new'ed, when you are done with it.
PS: I highly doubt it that you need to dynamic allocate a standard container (like std::map), but if you really are sure that you need to use, then consider using std::unique_ptr.

Would be destroyed dinamic allocated memory asigned to ThisMap too?
No, the rule of thumb before C++11 was that if you new something, you must delete it later.
Since C++11, you are very strongly encouraged to use smart pointers, which deal with allocation/deallocation for you in a safe manner. std::unique_ptr's documentation is a good starting point.

No.
1. If you want ThisMap to be A's data field, you have to declare and implement your own destructor, so your code should be like:
class A
{
std::map<std::string, std::string> *ThisMap;
void f();
~A();
};
void A::f()
{
ThisMap = new map<std::string, std::string>;
//more code (a delete will not appear)
}
A::~A()
{
if(ThisMap) delete ThisMap;
}
2. If ThisMap is just a function variable, so you just have to delete it at the end of the use, like:
void A::f()
{
map<string, string> *ThisMap = new map<std::string, std::string>;
//more code (a delete will not appear)
delete ThisMap;
}
Notice that its A::f and not A:f
:)

Related

try finally how to free memory

I am new to C++ in VS C++. I'm creating win32 dll library. I have a major basic problem with try finally block.
Let's pretend I have something like this:
class object {
private:
int* foo;
public:
object() : foo(new int()) { *foo = 42; }
~object() {
// Now since foo is dynamically allocated, the destructor
// needs to deallocate it
delete foo;
}
};
int main() {
vector<object*> tmp;
tmp.push_back(new object());
// Do some stuff with tmp
for (int i = 0; i < tmp.size(); ++i) {
delete tmp[i]; // Calls ~object (which deallocates tmp[i]->foo)
// and deallocates *tmp[i]
}
tmp.clear();
return 0;
}
I have copied the code snippet from:
Another stackoverflow question
In the above example, how can I use the "free" part so that it could be always freed up as the method finishes its job? I thought try finally should suffice.
But now I can see that there are several: try, __try Don't know what is the difference. With __try I get compiler errors which says something about RAII ...
Could anyone help me with this?
It's Resource Acquisition Is Initialization, RAII for short. The idea there being that if an object owns a resource, its destructor should free it automatically. In all of these cases, with C++11 you'd want to use std::unique_ptr instead of raw pointers. So, for instance:
class object {
std::unique_ptr<int> foo;
public:
object() : foo(std::make_unique<int>(42)) { }
// no destructor necessary here
};
int main() {
std::vector<std::unique_ptr<object>> tmp;
tmp.push_back(std::make_unique<object>());
// when tmp goes out of scope, each object in it will already
// be deleted for you, no code necessary
}
Of the many advantages here is the fact that now you don't have to worry about writing the copy constructor for object (as-is, your foo will get deleted twice if you copy it). See also Rule of Zero
There are various ways.
One is to make the vector<object *> a vector<unique_pointer<object> >. No need to explicitly deallocate the objects at all.
Another is to place the vector<object *> a member of another class that manages the deallocation. So, when an instance of that class is destroyed, its destructor releases all the elements of the vector in your code. You will need to supply other constructors and member functions for that class, to manage adding objects to the vector properly.

Should I delete things created by the new keyword in main.cpp?

If I understand correctly (which I am not claiming I do), you should delete anything created with the new keyword in your Destructor for a particular class. That prevents memory leaks. Example:
#include "Bar.h"
Bar *bar_ = NULL;
Foo::Foo()
{
bar_= new Bar;
}
Foo::~Foo()
{
delete bar_;
bar_ = NULL;
}
But should you delete new things created in main.cpp? Or will they just be automatically deleted by their Destructors when they go out of scope?
#include "Foo.h"
int main()
{
MakeNewFoo();
//Do other stuff and forget foo ever existed
exit(0);
}
void MakeNewFoo(){
Foo *foo = new Foo;
}
Short answer: Yes, clean up your memory.
Longer answer:
I don't know of an OS that won't clean up memory leaks created by you, but you should do it anyway. It becomes especially helpful when you are running a memory leak detection tool, and aren't deluged by a bunch of "false" positives from main.cpp.
Besides, what about something like this?
int main()
{
BigStructure foo* = new BigStructure(/*...*/);
// some computations to get variables
// at this point foo is no longer needed
RestOfProgramFunction1(); // long running, resource heavy
RestOfProgramFunction2(); // long running, resource heavy
}
Now you've held onto a bunch of memory you don't need anymore, which leaves less memory available for the other functions you'll need.
You are responsible for freeing up any memory you allocate. If you don't want to care about when to do it, use a smart pointer like std::unique_ptr or std::shared_ptr, which will free up the memory for you when they go out of scope.
" Or will they just be automatically deleted by their Destructors when they go out of scope?"
No, they wouldn't be deleted, you'll get memory leaks.
In general you don't use new/delete directly in C++. You rather use a smart pointer from the standard Dynamic memory management classes:
class Foo {
unique_ptr<Bar> bar_;
public:
Foo() : bar_(new Bar) {}
~Foo() {} // delete is automatically managed by unique_ptr<Bar>
};
Same for your free function sample:
void MakeNewFoo(){
std::unique_ptr<Foo> foo(new Foo());
// Do stuff with foo
} // Will be deleted as soon foo goes out of scope
But if you use new/new[] you always have to cleanup using delete/delete[], yes.
Everything you create with new will exist during the whole execution of your program in memory, or when it is removed using delete. So yes, you should delete Foo before exiting MakeNewFoo.
First, the code you showed will not compile, because new returns a pointer, but your foo and bar_ variables are not declared as pointers, so you need to fix that:
#include "Bar.h"
Bar *bar_ = NULL;
Foo::Foo()
{
bar_= new Bar;
}
Foo::~Foo()
{
delete bar_;
bar_ = NULL;
}
#include "Foo.h"
int main()
{
MakeNewFoo();
//Do other stuff and forget foo ever existed
exit(0);
}
void MakeNewFoo(){
Foo *foo = new Foo;
}
Now, with that said, you can see that MakeNewFoo() has a memory leak, since the Foo object being allocated with new is never freed using delete. Yes, technically the OS will reclaim the memory when the process terminates. But what if MakeNewFoo() were called in other places of your code besides main()? So it is good practice to always delete whatever you new (or let C++ do it for you, via the std::auto_ptr, std::unique_ptr, and std::shared_ptr smart wrapper classes).

Freeing memory of container members

I'm trying to clear up my understanding of some memory issues in C++, primarily with containers containing pointers. Say I have something like this:
Header.H
#ifndef test_Header_h
#define test_Header_h
#include <vector>
using std::vector;
class ClassA {
int* intPtr;
public:
ClassA(int n);
~ClassA();
};
class ClassB {
vector<ClassA*> vecPtr;
public:
ClassB();
~ClassB();
void someFunc();
};
#endif
main.cpp
#include <iostream>
#include "Header.h"
int main(int argc, const char * argv[])
{
ClassA objA(5);
ClassB objB;
return 0;
}
ClassA::ClassA(int n) {
intPtr = new int[n];
}
ClassA::~ClassA() {
delete intPtr;
}
ClassB::ClassB() {
vecPtr = vector<ClassA*>(0);
}
ClassB::~ClassB() {
//no destructor needed
}
void ClassB::someFunc() {
//vecPtr = something using new;
int* testPtr = new int[vecPtr.size()];
//do stuff
delete testPtr;
}
Does vecPtr ever need to be deleted? Or does the destructor of ClassA accomplish this for me? Also, if instead of having a vector, would it be the same situation if I had used a list of pointers or a pair? Finally, for clarification testPtr needs to be deleted in someFunc because that is the scope it was declared in, so putting it in the destructor would be pointless. If testPtr shared the address the address of an important member, deleting it would also the important member? I know there is quite a few questions but I think I'm just going around in a circular argument in my head, confusing myself more and more.
vecPtr does not need to be deleted, because it is not a pointer. This might be different for the pointers in vecPtr and depends on who has the ownership for those pointers.
Yes, testPtr must be deleted, where it is available. Anything else won't even compile. If you point testPtr to a member and delete that, you will likely see a double free or corruption error when the member would be deleted on the destructor.
In general where something must be deleted is up to the implementation. The only thing that you need to look out for is that every new gets exactly one delete from somewhere in any code path. Usually constructors/destructor are therefore a good place.
You have big problems here. Remember this:
1) any new must be balanced with a delete.
2) any new[] must be balanced with a delete[].
In fact, if you mix them (as you've done), you have undefined behaviour. Boom! You need to write delete[] intPtr; and delete[] testPtr;
Also and simply put, you don't write delete vecPtr since you didn't write new vecPtr.
Internally, the C++ runtime remembers the number of elements that you've allocated using new[]. You need to use delete[] to allow that runtime to access that information.

c++ Do Local variables, with reserved memory, need to be freed?

I've a simply question.
I have been looking for the answer but I might not found the correct tags or words to find the solution...
The question is, as the title says: Do local variables (which have reserved memory) need to be freed? I meant, for example, if I've got the following function:
myClass* myFunction(){
myClass* A = new myClass;
return A;
}
In case of "yes", where Should I call "delete"? both before and after "return" are nonsense...
Am I right?
Don't use new unless you need to.
This avoids new, and so doesn't need deleting
myClass myFunction(){
myClass A;
return A;
}
If you think you need pointers, consider using smart pointers.
If you want the excitement of raw pointers, this function returns a raw pointer to the caller, and they must delete it when they are done.
myClass * myFunction(){
myClass * A = new myClass;
return A;
}
myClass * thing = myFunction();
//stuff, that might throw an exception, so watch it
// smart pointers FTW
delete thing;
Assuming that your type is defined something like this:
class myClass { /* ... */ };
Your example is not proper C++ (unless you have a myClass* conversion constructor, which you probably don't).
You do not have to new an object that sits on automatic memory:
myClass myFunction(){
myClass a;
return a;
}
When newing an object on dynamic memory, you can then put it into a pointer variable in automatic memory:
myClass* myFunction(){
myClass* a = new myClass;
return a;
}
Here, a might leak, if it isn't freed by the caller.
Presumably, unless you're doing some interesting operator overloading, you mean to assign new myClass to a pointer and return the pointer
myClass *myFunction(){
myClass *A = new myClass;
return A;
}
If that is the case, then yes, you will have to delete it at some point. It will be up to the caller of this function to keep the pointer and delete it when appropriate.
Alternatively you can use smartpointers.
Use shared_ptr instead of raw pointers.
std::shared_ptr<myClass> myFunction()
{
std::shared_ptr<myClass> A = std::make_shared<myClass>(constructor parameters, if any);
return A;
}
void f()
{
std::shared_ptr<myClass> A = myFunction();
}
This will emulate Java-style garbage collection.

stl vector memory management

I am using borland 2006 c++, and have following code. I am using vectors, and have trouble understanding why the destructor is not being called.
basically i have a class A
class A
{
private:
TObjectList* list;
int myid;
public:
__fastcall A(int);
__fastcall ~A();
};
__fastcall A::A(int num)
{
myid = num;
list = new TObjectList();
}
__fastcall A::~A()
{
delete list;
}
int main(int argc, char* argv[])
{
myfunc();
return 0;
}
void myfunc()
{
vector<A*> vec;
vec.push_back(new A(1));
vec.push_back(new A(2));
}
according to what i read, when variable vec goes out of scope in myfunc(), it should destruct its contained elements, so the destructor for A should be called. I have a breakpoint at ~A(), but never gets called, i have tried resize(), erase methods also
TIA
vec does destruct its elements when it goes out of scope. The problem here is that vec's elements are the pointers to A objects, not A objects themselves. If you instead did
vector<A> vec;
vec.push_back(A(1));
vec.push_back(A(2));
...then things would work as you expect.
ETA: note, though, that if you do this you have to define a copy constructor for A. That should involve doing a deep copy of the TObjectList member. Otherwise, when you copy an A object you'll wind up with two objects both pointing to the same TObjectList, and your program will crash when the second object is destroyed.
The destructor for A isn't called because you don't have a vector of A. You have a vector of pointers to A, and the destructors for the pointers are called. Pointers don't have a destructor, so nothing happens.
One way to delete everything would be to manually do something like
while (!vec.empty())
{
delete vec.back();
vec.pop_back();
}
Lots of good answers already, but I'll add one more:
Use boost::ptr_vector from the Boost Pointer Container Library, instead of std::vector. It will delete the objects when the vector goes out of scope, thus calling the destructors.
Grab the Boost libraries, and wherever you have a raw pointer in the above you use boost::shared_ptr<> instead. (Well, not in the signature of main().)