I have a code which looks ok, but when I run Valgrind
it is showing leak for fields which is allocated with new in setNumberOfFields()
function. Here are excerpts of my code:
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 Output:
==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)
I am not sure why it is showing leak at line 335 whereas the destructor is called for the arcField
object. I am not sure about this error. I guess the destructor of arcRecord
is not getting called which is not deleting the arcField
object.
I am by far, not an expert in C++ / Valgrind, but I think you could have a memory leak if arcRecord::setNumberOfFields
is called multiple times.
In such cases the pointer to the arcField[]
stored in fields
would simply be replaced by the new one pointing to the memory allocated by the new arcField[num]
, without the existing array in memory being actually deleted.
The destructor would only be able to delete the most recently allocated arcField[]
, (to which fields
points) but not the ones allocated previously, to which you would have no pointer at all.
You should maybe initialise all your pointers to 0
:
char *recordType = 0;
int numberOfFields = 0;
arcField *fields = 0;
and then in arcRecord::setNumberOfFields
check if fields
is set already and if yes, delete it before allocating.
void arcRecord::setNumberOfFields(int num) {
if(fields) {
delete [] fields;
}
fields = new arcField[num];
}