【问题标题】:Memory leak reported by valgrind in compositionvalgrind 在组合中报告的内存泄漏
【发布时间】:2018-02-02 09:54:45
【问题描述】:

我有一个看起来不错的代码,但是当我运行Valgrind 时,它显示在setNumberOfFields() 函数中分配了新的字段的泄漏。以下是我的代码摘录:

class arcField {
public:
    arcField();
    ~arcField();
};

arcField::arcField(){}

arcField::~arcField() {}

class arcRecord {
public:
    char       *recordType;                    
    int         numberOfFields;                 
    arcField   *fields;     

    arcRecord(){}
    ~arcRecord();
    void setNumberOfFields(int num);
};

arcRecord::~arcRecord() {
    if(fields) {
        delete [] fields;
    }
    fields = 0;
}

void arcRecord::setNumberOfFields(int num) {
       if(fields) {
       delete [] fields;
    }
    fields = 0;
    fields = new arcField[num];   // line number 335
}

int main() {
    int index = 1;
    arcRecord records[1];
    for(int i = 0; i <= 1; i++) {
    records[i].setNumberOfFields(index);  
    return 0;
}

记录[i].setNumberOfFields(tmp_int); // valgrind.records 中的 940 行是 arcRecord 类型的对象。

Valgrind 输出:

==12647== 8 bytes in 1 blocks are definitely lost in loss record 33 of 642
==12647==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
**==12647==    by 0x705BC8: arcRecord::setNumberOfFields(int) (recordFF.cc:335)**
==12647==    by 0x707B2F: arcRecordList::loadConfigFile(cvConfig&) (recordFF.cc:940)
==12647==    by 0x7078C7: arcRecordList::loadConfigFile(char const*) (recordFF.cc:894)
==12647==    by 0x70771D: arcRecordList::arcRecordList(char const*) (recordFF.cc:883)
==12647==    by 0x5EE131: cvComericaArchive::cvComericaArchive() (cvComericaArcFuncs.cc:62)
==12647==    by 0x45581F: ArchInterface::ArchInterface(std::string const&, char const*) (ArchInterface.cc:115)

我不确定为什么它在第 335 行显示泄漏,而为 arcField 对象调用析构函数。我不确定这个错误。我猜arcRecord 的析构函数没有被调用,它不会删除arcField 对象。

【问题讨论】:

  • arcField::~arcField() { delete this; } 这看起来像Harakiri。我可以想象 Valgrind 不喜欢它。这是我第一眼看到的。我会删除delete this;,重新编译,看看是否变好了。
  • 你在析构函数中销毁类,然后尝试删除它的字段

标签: c++ memory-leaks valgrind composition


【解决方案1】:

到目前为止,我还不是 C++/Valgrind 方面的专家,但我认为如果 多次调用 arcRecord::setNumberOfFields,您可能会发生内存泄漏。

在这种情况下,存储在fields 中的指向arcField[] 的指针将简单地替换为指向new arcField[num] 分配的内存的新指针,没有现有的内存中的数组实际上被删除了

析构函数只能删除最近分配的 arcField[],(fields 指向)但不能删除之前分配的那些,你根本没有指针.

你也许应该初始化所有指向0的指针:

char       *recordType = 0;
int         numberOfFields = 0;
arcField   *fields = 0;   

然后在arcRecord::setNumberOfFields 中检查fields 是否已设置,如果是,请在分配前将其删除。

void arcRecord::setNumberOfFields(int num) {
    if(fields) {
        delete [] fields;
    }
    fields = new arcField[num];
}

【讨论】:

  • @Karan 您不应该根据答案更新问题中的代码,因为其他用户无法再理解原始问题。问题应该保持原样,以便其他 Stackoverflow 访问者可以从中学习
  • 谢谢你的建议,其实是我发错了想删的帖子,但是因为别人花时间,所以删不掉。这是我现在发布的原始问题。顺便说一句,现在通过在调用函数 setNumberOfFields 的循环结束时显式调用析构函数来解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 2012-10-25
相关资源
最近更新 更多