0

After reading: C++ Array of pointers: delete or delete []? (reply by shai vashid) and http://www.cplusplus.com/forum/beginner/6651/

I implemented following:

Kernel.h

unsigned int **ConfigMeM;
//.....
~Kernel(){ //destructor
    for (unsigned int i=0; i<MeMSize; i++)
        delete [] MeM[i]; //Valgrind:- Invalid read of size 4
                                       - Invalid free() / delete / delete[] / realloc()
    delete [] MeM; //Valgrind: Invalid free() / delete / delete[] / realloc()

    for (unsigned int i=0; i<_item_tot; i++)
        delete [] ConfigMeM[i]; //Valgrind: Same comments as above
    delete [] ConfigMeM; //Valgrind: same as above
};

Kernel.cpp

//.......
MeM = new unsigned int*[MeMSize];
for (unsigned int i=0; i<MeMSize; i++){
    MeM[i] = new unsigned int[11]; //Valgrind: 14,608 bytes in 332 blocks are definitely lost in loss record 2,021 of 2,036
}
for (unsigned int i=0; i<MeMSize; i++){
    for (int j=0; j<10; j++){
        MeM[i][j] = 0;
    }
}
 //.....
 ConfigMeM = new unsigned int*[_item_tot];
for (unsigned int i=0; i<_item_tot; i++){
    ConfigMeM[i] = new unsigned int[3]; //Valgrind: 1,200 bytes in 100 blocks are definitely lost in loss record 1,131 of 2,036 
}
for (unsigned int i=0; i<_item_tot; i++){
    for (int j=0; j<3; j++){
        ConfigMeM[i][j] = 0;
    }
}
  //.....

I am not sure what I am doing wrong.

Any suggestions please?

Thank you.

Community
  • 1
  • 1
algoProg
  • 718
  • 2
  • 11
  • 27
  • Are you running the code in Kernel.cpp multiple times? – Kerrek SB Nov 27 '12 at 13:36
  • Is the code from Kernel.cpp part of the constructor, or something else? Are you declaring your own copy constructor and copy-assignment operator (per the [Rule of Three](http://stackoverflow.com/questions/4172722))? My guess is that you aren't, and you're ending up with two objects trying to delete the same memory. – Mike Seymour Nov 27 '12 at 13:39
  • @KerrekSB Yes, you are right! In a top module several copies of Kernel are created. For example in the current example it is 64. How does that matter here?! – algoProg Nov 27 '12 at 14:05
  • "How does it matter?" Think about this: `int * p = new int; p = new int; p = new int; delete p;` – Kerrek SB Nov 27 '12 at 14:07
  • @KerrekSB I did not mean to challenge you!! I just want to ask now what can I do to and how shall I modify my code? – algoProg Nov 27 '12 at 14:12
  • I wasn't feeling challenged :-) I just gave you a simple example that demonstrates the problem, as well as suggests the solution: delete the existing object before allocating a new one! – Kerrek SB Nov 27 '12 at 18:09

1 Answers1

1

My best guess is that an object your class is being copied using the implicitly-generated copy constructor or copy-assignment operator. This would leave two objects with pointers to the same memory; both would try to delete this memory on destruction, resulting in double-delete errors.

The easiest fix is to prevent copying by deleting these functions:

Kernel(Kernel const&) = delete;
void operator=(Kernel const &) = delete;

or, if you're stuck with an ancient compiler, declare them private with no function body.

If you need to copy these objects, then you will need to implement these, perhaps to perform a "deep copy" that allocates new blocks of memory.

Alternatively, it might be easier to use std::vector to manage your dynamic arrays; this already has correct copy semantics, and can be initialised quite simply:

std::vector<std::vector<unsigned int>> MeM, ConfigMem;

(MemSize, std::vector<unsigned int>(11));
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644