Andro Miguel M. Bondoc
Andro Miguel M. Bondoc

Reputation: 732

Destructor in C++

I had made a header file with a class named cmysqldb with a lot of pointers. My problem is now this:

How could i create a destructor that will delete the pointers that may cause potential memory leak?

here is the header code:

#ifndef CMSYQLDB_H
#define CMSYQLDB_H

#include <QMultiMap>
#include <QStringList>
#include "mysql.h"

class cmysqldb
{

public:
    cmysqldb::~cmysqldb()
    {
        const char *text,
        MYSQL *connection,
        MYSQL_RES *result,
        MYSQL_RES *fresult,
        MYSQL_FIELD *mfield
    }
    int query_state;
    int numfields;
    MYSQL mysql;
    MYSQL_ROW row;
    MYSQL_ROW fieldrow;


   ....


};


#endif // CMSYQLDB_H

is this what you mean???

Upvotes: 0

Views: 1442

Answers (4)

Ben Voigt
Ben Voigt

Reputation: 283614

The best thing to do would be to use smart pointers to store all the pointers to related objects. C++ will automatically call destructors of all sub-objects when the parent object is destroyed.

And if your parent object fails partly constructed, its destructor won't be called. So any pointers already allocated would leak if you design things to be freed in the destructor. However, subobjects destructors get run if the subobject was allocated, so by using smart pointers this partly allocated case is taken care of for you.

For more information, look up RAII (Resource Acquisition Is Initialization).

Upvotes: 0

Mahesh
Mahesh

Reputation: 34605

Resources acquired through new should be deallocated using delete and with new[] should be with delete[]. As simple as that to avoid memory leaks. Could be more helpful if you post more specific code.

Destructor bears the same name of the class, except that it has a ~ symbol before it.

cmysqldb :: ~cmysqldb()
{
    // deallocate the resources with the above mentioned rule 
}

class foo
{
    int var ;
    int *ptr ;

    public:

        foo()
        {
             ptr = new int ;
        }

        ~foo()
        {
             delete ptr ;
        }
};

void bar()
{

    foo obj ;

    // .....

} // <-- obj goes out of scope and it's destructor is called at this point.

foo class has two member variables var, ptr of type int, int* respectively. So, bytes required to hold an integer in var and pointer(ptr) that can point to an integer's address is automatically allocated. These resources are not allocated by us. So, it's not our responsibility to deallocates these resources. So far so good.

ptr = new int ;

new int acquires resources from the free store that can hold an int and it's address is returned which ptr holds. Now, this acquisition of resource from free store is because of the new operation defined by the user. So, it's the job of the user to return the resources back to the free store. So, the statement in the destructor -

delete ptr ;

Get a book from The Definitive C++ Book Guide and List which can even explain better. Also follow @Michael advice of using smart pointers which manages resources automatically.

Upvotes: 2

Michael Aaron Safyan
Michael Aaron Safyan

Reputation: 95449

In order to delete the pointers, you will need to store them somewhere. It is unclear where you do this (you don't have fields for all the pointer parameters accepted by the constructor), so I won't be able to give you exactly the code to do this, but I will lay out how you can go about doing this.....

To declare the destructor, add the following to your class declaration:

~cmysqldb();

Note that if your class will have any virtual methods, you should instead declare it as:

virtual ~cmysqldb();

And in your source file add:

cmysqldb::~cmysqldb()
{
    // contents of your destructor goes here.
}

Now, how exactly you free your resources depends on how they were allocated. If you used some library-specific create function and there is a library-specific free function, then use that. If it was allocated using malloc, then use free; if it was allocated with new, use delete; if it was allocated using new[], then use delete[]. Also, you should use smart pointer classes such as boost::scoped_ptr (std::unique_ptr) or boost::shared_ptr (std::shared_ptr), wherever possible to avoid explicitly managing these resources via new/delete in your constructors / destructors.

One last, very important point... whenever you have a function that accepts a pointer, it is very important that you document the ownership semantics. Is it owned by the caller? Is ownership transferred? Etc.

Upvotes: 2

Alok Save
Alok Save

Reputation: 206498

A memory leak occurs when you acquire dynamic memory using new or new[] & do not deallocate the memory using delete or delete[]`.

Your constructor declaration is of the type:

cmysqldb(const char *text, MYSQL *connection, MYSQL_RES *result, 
         MYSQL_RES *fresult, MYSQL_FIELD *mfield);  

You should keep a track of whatever dynamic memory allocations you are doing in the constructor with new and new[]and you should deallocate all of them with a corresponding delete or delete[].

Upvotes: 0

Related Questions