Alright so Say I have a class with all its definition, bla bla bla...
template <class DT>
class Foo{
private:
DT* _data;
//other stuff;
public:
Foo(DT* data){ _data = data; }
virtual ~Foo(){ delete _data; }
//other methods
};
And then I have in the main method:
int main(){
int number = 12;
Foo<anyRandomClass>* noPrimitiveDataObject = new Foo<anyRandomClass>(new anyRandomClass());
Foo<int>* intObject = new Foo<int>(number);
delete noPrimitiveDataObject; //Everything goes just fine.
delete intObject; //It messes up here, I think because primitive data types such as int are allocated in a different way.
return 0;
}
My question is: What could I do to have both delete statements in the main method work just fine?
P.S.: Although I have not actually compiled/tested this specific code, I have reviewed it extensively (as well as indented), so if you find a mistake, please be nice.
You're taking the address of a literal and then calling delete on it later, which is wrong. It was not allocated with new, therefore you cannot deallocate it with delete (nor would it make any sense to).
If you had written new int(12) instead it would be ok, however, there are other problems.
First, your class violates The Rule of Three. What happens if I copy intObject and then call delete on both of them? You end up calling delete on the same pointer twice.
Second, why are you allocating these things dynamically to begin with? You create an RAII style wrapper to handle deallocation for you... and then proceed to allocate it manually. What problem is that solving?
I suppose this is an exercise for you, and that's great. Just remember what problem you're trying to solve with this code.
If I am using a std::vector<T> I am certainly not going to use it like this:
std::vector<int> *v = new std::vector<int>;
It defeats the entire purpose of using a vector! Now I have to manually manage this pointer/memory, and that's the problem that the vector class (and other RAII style classes) were created to solve.
So, to use it properly, you do this:
void foo()
{
std::vector<int> v;
// do stuff with v
// it allocates its memory dynamically so you don't have to.
// when we exit the function the destructor is called, the memory
// deallocated, and life continues as it should.
}
Use automatic storage duration to your advantage, that's the whole point. Also be very clear about who owns the memory. If it is not clear from your class design who owns a given chunk of memory then it is not safe to delete it in your destructor.
Ok, you changed the code to this now:
int number = 12;
// ...
Foo<int>* intObject = new Foo<int>(number);
Same problem; you are taking the address of a variable allocated with automatic storage duration and then calling delete on it. This is wrong. Anything you allocate with new you deallocate with delete, but nothing else. Ever. That's it.
It seem like you didn't know you can do new int(12). So for example you could change your code to the following:
Foo<int>* intObject = new Foo<int>(new int(12));
(I'm assuming this is just for learning, as not using new altogether would be better).
Also, I just noticed your code is wrong, perhaps you wanted the following:
Foo(DT* data){ _data = data; }
virtual ~Foo(){ delete _data; }
Side Note
Before posting a question, at least try to compile your examples.
Related
According to the following article: Why isn’t the destructor called at the end of scope?
Code that creates an object using new and then deletes it at the end of the same scope is ugly, error-prone, inefficient, and usually not exception-safe. For example:
void very_bad_func() // ugly, error-prone, and inefficient
{
X* p = new X;
// use p
delete p; // not exception-safe
}
My Code which I hope is not ugly:
I am creating an object of type TiXmlDocumentand the delete it by the end of the function.
void DataLoader::readXmlFile(const string & file)
{
TiXmlDocument *doc = new TiXmlDocument(file.c_str());
bool loadOkay = doc->LoadFile();
TiXmlHandle hdl(doc);
//work is done in here
if(loadOkay)
{
TiXmlElement * pRoot = hdl.FirstChildElement().Element();//.FirstChildElement().Element();
parseFile(pRoot);
}
else
{
cout <<"Error: "<< doc->ErrorDesc()<<endl;
}
//deallocate doc
delete doc;
}
Question(s):
Should I use DataLoader::~DataLoader() {} destructor in order to insure that the object is deleted after I leave the scope of the function? without the need of explicitly deleting it delete doc.
As suggested I did the following:
TiXmlDocument doc(xmlFile.c_str());
bool loadOkay = doc.LoadFile();
TiXmlHandle hdl(&doc);
I am starting to think that using dynamic memory just like java and c# is not a good practice (should be used in a responsible way) in c++. If there is no real cause to use it then don't. If not handled correctly it will cause a memory leak which is hard to trace.
Either create your object without new:
void func()
{
X p;
// use p
}
Or if you must use new (for example, it's a big object) then use a smart pointer:
void func()
{
std::unique_ptr<X> p(new X);
// use p
}
Problem solved!
That's still ugly (in my view), and certainly error-prone, inefficient, and not exception-safe. If an exception is thrown during this function, the delete won't happen, and you'll leak memory.
In this case, there's no need for new at all; use an automatic variable, which will be destroyed automatically when the function exits, whether by reaching the end, returning, or throwing.
TiXmlDocument doc(file.c_str());
If you did need dynamic allocation for some reason, then use a smart pointer or other RAII type to get the same automatic behaviour:
auto doc = std::make_unique<TiXmlDocument>(file.c_str()); // C++14 or later
std::unique_ptr<TiXmlDocument> doc(new TiXmlDocument(file.c_str())); // C++11
To answer the last question: use the destructor to deallocate resources managed by the class instance, not transient resources used within a function call. Again, you should usually use RAII types as member variables to manage these resources automatically, so that you don't need to write a destructor yourself.
I'm trying to answer some past paper questions that I've been given for exam practice but not really sure on these two, any help be greatly appreciated. (Typed code up from image, think it's all right).
Q1: Identify the memory leaks in the C++ code below and explain how to fix them. [9 marks]
#include <string>
class Logger {
public:
static Logger &get_instance () {
static Logger *instance = NULL;
if (!instance){
instance = new Logger();
}
return *instance;
}
void log (std::string const &str){
// ..log string
}
private:
Logger(){
}
Logger(Logger const&) {
}
Logger& operator= (Logger const &) {
}
~Logger() {
}
};
int main(int argcv, char *argv[]){
int *v1 = new int[10];
int *v2 = new int[20];
Logger::get_instance() . log ("Program Started");
// .. do something
delete v1;
delete v2;
return 0;
}
My answer is that if main never finishes executing due to an early return or an exception being thrown that the deletes will never run causing the memory to never be freed.
I've been doing some reading and I believe an auto_ptr would solve the problems? Would this be as simple as changing lines to?? :
auto_ptr<int> v1 = new int[10];
auto_ptr<int> v2 = new int[20];
v1.release();
delete v1;
Q2: Why do virtual members require more memory than objects of a class without virtual members?
A: Because each virtual member requires a pointer to be stored also in a vtable requiring more space. Although this equates to very little increase in space.
Q1: Note that v1 and v2 are int pointers that refer to an array of 10 and 20, respectively. The delete operator does not match - ie, since it is an array, it should be
delete[] v1;
delete[] v2;
so that the whole array is freed. Remember to always match new[] and delete[] and new and delete
I believe you're already correct on Q2. The vtable and corresponding pointers that must be kept track of do increase the memory consumption.
Just to summarize:
the shown program has undefined behavior using incorrect form of delete, so talking about leaks for the execution is immaterial
if the previous was fixed, leaks wold come from:
new Logger(); // always
the other two new uses, if subsequent new throws or string ctor throws or the ... part in log throws.
to fix v1 and v2 auto_ptr is no good ad you allocated with new[]. you could use boost::auto_array or better make v array<int, 10> or at least vector<int>. And you absolutely don't use release() and then manual delete, but leade that to the smart pointer.
fixing instance is interesting. What is presented is called the 'leaky singleton' that is supposed to leak the instance. But be omnipresent after creation in case something wants to use it during program exit. If that was not intended, instance shall not be created using new, but be directly, being local static or namespace static.
the question is badly phrased comparing incompatible things. Assuming it is sanitized the answer is that a for a class with virtual members instances are (very likely) to carry an extra pointer to the VMT. Plus the the VMT itself has one entry per virtual member after some general overhead. The latter is indeed insignificant, but the former may be an issue, as a class with 1 byte of state may pick up a 8 byte pointer, and possibly another 7 bytes of padding.
Your first answer is correct to get credit, but what the examiner was probably looking for is the freeing up of Logger *instance
In the given code, memory for instance is allocated, but never deallocated.
The second answer looks good.
instance is never deleted and you need to use operator delete[] in main().
Q1:
few gotchyas -
singleton pattern is very dangerous, for example it is not thread safe, two threads could come in and create two classes - causing a memory leak, surround with EnterCriticalSection or some other thread sync mechanism, and still unsafe and not recommended to use.
singleton class does not release they memory, singleton should be ref counted to really act properly.
you're using a static variable inside the function, even worse than using a static member for the class.
you allocate with new [] and delete without the delete[]
I suspect your question is two things:
- free the singleton pointer
- use delete[]
In general however the process cleanup will clean the dangling stuff..
Q2:
your second question is right, because virtual members require a vtable which makes the class larger
Suppose you have a simple class like this:
class foo{
private:
int* mData;
int mSize;
public:
foo(int size){
mSize = size;
mData = new int [mSize];
}
~foo() {
mSize = 0;
delete [] mData;
}
};
Then inside main you do:
int main () {
static int HUGE = 100000000;
foo a(HUGE);
// do something useful with a
// .
// .
// .
// Now I'm done with a; I do not need it anymore ...
foo b(HUGE);
// do something useful with b
// Ok we are done with b
return 0;
}
As you can see a is no longer needed after b, but since it is created on the stack, the destructor won't be called up until the end of the program. Now, I know this is not the same as allocating with new and forgetting to call delete, however this is still wasting memory. Do you consider this as "memory leak" or just a bad programming?
Also, How would you avoid situations like this? One way would be to manually call the destructor when the object is not needed anymore, but, besides looking ugly and unfamiliar!, you get into trouble of double free unless you change the destructor to something like:
foo::~foo(){
if (mData != NULL){
delete [] mData;
mData = NULL;
mSize = 0;
}
}
Another way is to create a on the heap via foo *pa = new foo (HUGE) and then call delete pa once the object is no longer needed. This works but at the danger of introducing another possible memory leak (if one forgets to call delete pa).
Is there any better way to get rid of unneeded objects?
Destructors are called when an object goes out of scope. C++ allows arbitrary scopes inside function bodies. Write your main function this way:
int main () {
static int HUGE = 100000000;
{
foo a(HUGE);
// do something useful with a
// Now I'm done with a; I do not need it anymore ...
}
{
foo b(HUGE);
// do something useful with b
// Ok we are done with b
}
// etc.
return 0;
}
I see your example is simplified, but in a real program, don't forget to either
implement an appropriate copy constructor and operator= for foo or
add a declaration for a private copy constructor and operator= so it cannot be called.
Just place your huge a and b objects into their own braces if you are worried about scope.
And this isn't technically a memory leak, but it is very poor memory management as you have stated.
{
{
foo a(HUGE);
}
...
{
foo b(HUGE);
}
No, it's definetely not a memory leak.
A memory leak is when you allocate memory and you lose its handle, so you can't free it afterwards. It doesn't matter where or when you free the memory, as long as you do.
You could add an enclosing scope to force memory freeing:
{
foo a(HUGE);
}
{
foo b(HUGE);
}
This is not a memory leak, because you don't loose track of your allocated memory. However this is slightly ineffective, especially when the program is running longer, and should be avoided.
You can use scopes to shorten the lifetime of an object:
int main () {
static int HUGE = 100000000;
{
foo a(HUGE);
// do something useful with a
// .
// .
// .
// Now I'm done with a; I do not need it anymore ...
}
{
foo b(HUGE);
// do something useful with b
// Ok we are done with b
}
return 0;
}
Also, it is worth reconsidering if this two parts of code should be in separate functions, then the allocated objects will be freed when returning from function.
The constructor of the class could also take a block of memory you allocated in your 'main()' function as a parameter. That way, once 'a' is done with the use of the memory block, you can pass it into 'b' as well. 'foo' destructor does not need to release any memory at all, and you don't need to be worried about wasting memory, or object lifetimes at all.
Do you consider this as "memory leak" or just a bad programming?
No, it is not memory leak.
How would you avoid situations like this?
Write small functions, few lines. Your code will be more readable and the unused variable allocated on the stack will be freed.
It's not a memory leak; however it precisely the sort of memory usage that Firefox developers have spent a long time fixing.
Scope is probably the easiest way to fix this, as Dark Falcon suggests. Alternatively move the allocations and related code into separate functions.
Also pointers can be more safely handled with std::auto_ptr so that they are freed when the scope is released.
Do you consider this as "memory leak"
No, unless you do something like longjmp in the middle.
or just a bad programming?
I consider using new[] to allocate array in your class bad programming practice, because you have std::vector for that.
Also, How would you avoid situations like this?
Enclose foo into scope:
{
foo a(HUGE);
}
unless you change the destructor to something like:
delete ignores null pointers. Destructor is called only once, so no need to zero variables. Calling destructor manually is a VERY BAD IDEA - it isn't meant for that. If you want to reinitialize the structure, implement clear() or resize() methods.
Is there any better way to get rid of unneeded objects?
Yes, enclose them into scopes.
It's not a memory leak, but if you have a variable that you need the
first half of a function, and not the second, there's a good chance that
the function is doing to much, and should be refactored into two (or
more) separate functions.
Extract functions to reduce the scope. Give them good names:
void do_a(int amount)
{
foo a(amount);
// ask `a` to be useful
}
void do_b(int amount)
{
foo b(amount);
// ask `b` to be useful
}
int main () {
static int HUGE = 100000000;
do_a(HUGE);
do_b(HUGE);
return 0;
}
I am not experienced in handling of the memory in a C++ program, so I would like a piece of advice in that case:
I want to create a new Object in a function in a class which is essential till the end of the program. As far as I am concerned, if I use the operator new, I should sometimes delete it. Taking into account that it must be initialized inside a class, when and how must I finally delete it?
I suggest the smart pointer idiom
#include <memory>
struct X
{
void foo() { }
};
std::share_ptr<X> makeX() // could also be a class member of course
{
return std::make_shared<X>();
}
int main()
{
std::share_ptr<X> stayaround = makeX();
// can just be used like an ordinary pointer:
stayaround->foo();
// auto-deletes <sup>1</sup>
}
If the pointer is truly a static variable, you can substitute a unique_ptr (which works similarly, but passes ownership on assignment; this means that the pointer doesn't have to keep a reference count)
Note To learn more about C++ smart pointers in general, see smart pointers (boost) explained
Note If you don't have the TR1/C++0x support for this, you can just use Boost Smartpointer
1 unless you are leaking copies of the shared_ptr itself; that would be some strange use of smart pointers previously unseen :)
Edit: Using some sort of smart pointer is often a good idea, but I believe it is still essential to have a solid understanding of manual memory management in C++.
If you want an object in a class to persist until the end of the program, you can simply make it a member variable. From what you've said, there's nothing to suggest you need to use new or delete here, just make it an automatic variable. If you did want to use new and delete for practice, you should read up on constructors and destructors for a class (you can and will use new and delete outside of classes, but I'm trying to keep this relevant to your question). Here's one I prepared earlier:
class Foo
{
public:
Foo(); // Default constructor.
~Foo(); // Destructor.
private:
int *member;
}
Foo::Foo() // Default constructor definition.
{
member = new int; // Creating a new int on the heap.
}
Foo::~Foo() // Destructor.
{
delete member; // Free up the memory that was allocated in the constructor.
}
This is a simple example, but it will hopefully help you out. Note that the variable will only persist as long as the object is alive. If the object is destroyed or goes out of scope, the destructor will be called and the memory will be freed.
You can use the smart pointer as suggested by Sehe or you can create a static object in the function and return a reference to it. You need not explictly delete the object, when the process terminates the object will be deleted. Like:
struct X {};
X& makeX() // could also be a class member of course
{
static X x;
return x;
}
int main()
{
X& stayaround = makeX();
}
On most operating systems (in particular Linux), if you allocate an object pointer with new Object, and don't bother delete-ing because you'll need it till the program ends, no harm is really done. There is some memory leak inside your program (you can use valgrind to hunt such leaks) but the kernel will release all the memory used by a process when it has ended.
A better alternative is to have a singleton class for the application data, like e.g. QApplication in Qt, ahd construct a single instance in that class early in your main, and have that class contain a smart or dumb pointer to your Object. The destructor should delete that object.
I've just started combining my knowledge of C++ classes and dynamic arrays. I was given the advice that "any time I use the new operator" I should delete. I also know how destructors work, so I think this code is correct:
main.cpp
...
int main()
{
PicLib *lib = new PicLib;
beginStorage(lib);
return 0;
}
void beginStorage(PicLib *lib)
{
...
if (command != 'q')
{
//let's assume I add a whole bunch
//of stuff to PicLib and have some fun here
beginStorage(lib);
}
else
{
delete lib;
lib = NULL;
cout << "Ciao" << endl;
}
}
PicLib.cpp
...
PicLib::PicLib()
{
database = new Pic[MAX_DATABASE];
num_pics = 0;
}
PicLib::~PicLib()
{
delete[] database;
database = NULL;
num_pics = 0;
}
...
I fill my PicLib with a Pic class, containing more dynamic arrays. Pic's destructor deletes them in the same manner seen above. I think that delete [] database gets rid of all those classes properly.
So is the delete in main.cpp necessary? Everything looking hunky dory here?
There are a couple of problems:
int main()
{
PicLib *lib = new PicLib;
beginStorage(lib);
return 0;
}
It is best to allocate and delete memory in the same scope so that it is easy to spot.
But in this case just declare it locally (and pass by reference):
int main()
{
PicLib lib;
beginStorage(lib);
return 0;
}
In beginStorage()
But I see no reason to manipulate a pointer. Pass it by reference and just use it locally.
void beginStorage(PicLib& lib)
{
....
}
In the PicLib class you have a RAW pointer: databases.
If you have a RAW pointer that you own (you create and destroy it) then you must override the compiler generated versions of the copy constructor and assignment operator. But in this case I see no reason touse a pointer it would be easier to just use a vector:
class PivLib
{
private:
std::vector<Pic> databases;
};
Yes, anything you create with new must be deleted with delete, and anything created with new[] must be deleted with delete[], at some point.
There are some things I'd point out in your code though:
Prefer std::vector<> over using new[] and delete[]. It'll do the memory management for you. Also have a look at smart pointers like auto_ptr, shared_ptr and in C++0x unique_ptr for automatic memory management. These help save you from forgetting a delete and causing a memory leak. If you can, don't use new/new[]/delete/delete[] at all!
If you have to new and delete something, it's a very good idea to new in a class constructor, and delete in a class destructor. When exceptions are thrown, objects go out of scope etc., their destructors are called automatically, so this helps prevent memory leaks. It's called RAII.
Having beginStorage delete its parameter is potentially a bad idea. It could crash if you call the function with a pointer not created with new, because you can't delete any pointer. It'd be better if main() created a PicLib on the stack rather than using new and delete, and for beginStorage to take a reference and not delete anything.
Yes it is necessary, unless you use an auto_ptr (and read up on the semantics of auto_ptr before you use it -- you can't copy it arround).
for example :
int main()
{
auto_ptr<PicLib> lib = new PicLib;
beginStorage(lib);
return 0;
} // auto_ptr goes out of scope and cleans up for you
else doesn't go with while. You'd want something more like:
void beginStorage(PicLib *lib)
{
while (command != 'q')
{
//let's assume I add a whole bunch
//of stuff to PicLib and have some fun here
}
delete lib;
lib = NULL; // Setting to NULL is not necessary in this case,
// you're changing a local variable that is about
// to go out of scope.
cout << "Ciao" << endl;
}
The delete looks good, but you should make sure to document that beginStorage takes ownership of the PicLib object. That way anyone using beginStorage knows that they don't have to delete it later.
The delete in main.cpp is necessary.
This is probably a matter of personal preference, but I would advise against calling new and delete in separate logical parts (here the delete call on the PicLib instance is in a separate function). Usually it's better to have the responsibility for allocation and deallocation given to just one part.
#AshleysBrain has a better suggestion (about creating PicLib the stack), although this might cause problems if PicLib takes up too much memory.
Generally you want to delete in the same place as you new. It makes the accounting easier. Better is to use a smart pointer (scoped_ptr in this case), which means that your code is still correct even if the body of the while throws an exception and terminates prematurely.
Everything looks good.
The delete in main.cpp is necessary because if you didn't call delete then the destructor is not run and your array is not deleted. You'd also be leaking the memory for the class, not just the array.
Yes, otherwise the destructor for PicLib will not be called.
One stylistic note though: If you new a method-scope object in a function, try and delete it in the same function. As a junior engineer that has had to go through large projects fixing other people's memory leaks...this makes things a lot easier for other people to read. From the looks of it, you could delete *lib after beginStorage() returns. Then it would be easier to see the scope of *lib in one place.