【问题标题】:Pointer to object with vector memory leak指向具有向量内存泄漏的对象的指针
【发布时间】:2013-04-06 13:00:24
【问题描述】:

我似乎对向量有一点内存泄漏问题。 我的代码如下所示:

    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;
    }

当我用 valgrind 运行这段代码时,它说存在内存泄漏,丢失的字节数等于向量 ptts 中的项目数 * CPartition 的大小。所以我猜我必须以某种方式清理那个向量。我已经尝试过了,但无济于事。

【问题讨论】:

    标签: c++ inheritance vector destructor memory-leaks


    【解决方案1】:

    您需要在 CPart 中有virutal destructor

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

    否则会出现以下情况;

      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;
        }
    

    【讨论】:

    • 谢谢,这对我帮助很大。
    【解决方案2】:

    您可以使用 valgrind 通过使用额外的泄漏检查参数来非常精确地隔离内存泄漏的来源,即:

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

    只要你的代码是用调试符号编译的,valgrind 就会准确地告诉你泄漏的来源。

    【讨论】:

      【解决方案3】:

      我不认为这部分是真的;

      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;
      }
      

      最好将struct CPartition 从你的类定义中去掉并去掉CDisk::CPartition::CPartition(int size, const string&amp; dsc),即:

      struct CPartition {
           int div_size;
           string disk;
      };
      

      要调用CPartition 实例的div_size 你应该这样做

      instance_of_CPartition->div_size
      

      如需进一步了解,请阅读structure tutorial

      我不确定这是否能解决您的问题,但这会解决您代码中的另一个问题。

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-27
        • 2017-03-10
        • 1970-01-01
        • 2012-11-15
        相关资源
        最近更新 更多