valgrind 在组合中报告的内存泄漏
Memory leak reported by valgrind in composition
我的代码看起来不错,但是当我 运行 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;
}
records[i].setNumberOfFields(tmp_int); // 940 line in valgrind.records is object of type 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
对象。
到目前为止,我不是 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];
}
我的代码看起来不错,但是当我 运行 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;
}
records[i].setNumberOfFields(tmp_int); // 940 line in valgrind.records is object of type 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
对象。
到目前为止,我不是 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];
}