简体   繁体   中英

Pointer to object with vector memory leak

I seem to have a little memory leak problem with vectors. My code looks like this:

    class CPart {
    public:
        virtual void print() = 0;
    };

    //some other classes

    class CDisk : public CPart {
    public:
        CDisk(int tp, int size);
        ~CDisk();
        virtual void print();
        void AddPartition(int size, const string & dsc);

        static const int MAGNETIC = 0;
        static const int SDD = 1;
    private:

        struct CPartition {
            CPartition(int size, const string & dsc);
            int div_size;
            string disk;
        };
        int type;
        int d_size;
        vector<CPartition> ptts;
    };

    CDisk::CDisk(int tp, int size) {
        type = tp;
        d_size = size;
    }

    CDisk::CPartition::CPartition(int size, const string& dsc) {
        div_size = size;
        disk = dsc;
    }

    void CDisk::AddPartition(int size, const string& dsc) {
        ptts.push_back(CPartition(size, dsc));
    }

    int main(int argc, char** argv) {
        CDisk disk(CDisk::SDD, 5000);
        disk.AddPartition(500, "disk1");
        CPart *disk2 = new CDisk(disk);
        delete disk2;
        return 0;
    }

When I run this code with valgrind, it says there are memory leaks and the number of bytes lost is equal to the number of items in vector ptts * size of CPartition. So I am guessing I have to clean that vector somehow. I have tried that but to no avail.

You need to have virutal destructor in CPart

 class CPart {
    public:
        virtual void print() = 0;
        virtual ~CPart(){};
    };

Otherwise you will get following scenario;

  int main(int argc, char** argv) {
        CDisk disk(CDisk::SDD, 5000);
        disk.AddPartition(500, "disk1");
        CPart *disk2 = new CDisk(disk);//CDisk created
        delete disk2;//But here only CPart is deleted leaving CDisks data in memory
        return 0;
    }

You can use valgrind to very precisely isolate the origin of memory leaks by using additional leak check parameters, ie:

valgrind --leak-check=full ./a.out

As long as your code is compiled with debug symbols, valgrind will tell you exactly where the leak is coming from.

I dont think this part is really true;

struct CPartition {
    CPartition(int size, const string & dsc);
     int div_size;
     string disk;
};

CDisk::CPartition::CPartition(int size, const string& dsc) {
    div_size = size;
    disk = dsc;
}

It is better to put struct CPartition out of your class definition and get rid of CDisk::CPartition::CPartition(int size, const string& dsc) ie:

struct CPartition {
     int div_size;
     string disk;
};

To call div_size of an instance of CPartition you should do

instance_of_CPartition->div_size

For further, read structure tutorial .

I'm not sure if this will solve your question but this will solve another problem in your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM