c++ - Where are the memory leaks? 2d array class -


i submitted program class , error message says there few memory leaks, cannot find them (i asked professor)

here error message:

==27796== heap summary: ==27796==     in use @ exit: 160 bytes in 2 blocks ==27796==   total heap usage: 192 allocs, 190 frees, 21,989 bytes allocated ==27796==  ==27796== 160 bytes in 2 blocks lost in loss record 1 of 1 ==27796==    @ 0x402adfc: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==27796==    0x804d5c2: sweepergrid::sweepergrid(sweepergrid const&) (in /tmp/grading20151030-8173-zfd6af-0/sweepertest) ==27796==    0x804bf57: main (sweepertest.cpp:357) 

and following code use new or delete:

// explicit-value constructor

 sweepergrid::sweepergrid(const int initialrows, const int initialcols, const int density){     if ((initialrows<5 || initialcols<5) || (density<25 || density>75)) {         throw out_of_range("grid not large enough (number of rows or columns cannot fewer 5) or density low or high (must between 25% , 75%)");     }  numrows = initialrows; numcolumns = initialcols; numbombs = 0;  grid = new sweepercell*[numrows]; for(int i=0; <numrows; i++){     grid[i] = new sweepercell[numcolumns]; }  srand(time(0)); for(int i=0; i<numrows; i++){     (int j=0; j<numcolumns; j++){         if(rand()%100+1<density){             placebomb(i, j);         }     } } } 

// copy constructor

sweepergrid::sweepergrid(sweepergrid const & source){     numrows=source.getrows();     numcolumns=source.getcolumns();     numbombs=source.getbombs();  grid = new sweepercell * [numrows]; for(int i=0; < numrows; i++){     grid[i] = new sweepercell[numcolumns]; }  for(int i=0; i<numrows; i++){     (int j=0; j<numcolumns; j++){         grid[i][j] = source.at(i, j);     } } } 

// destructor

sweepergrid::~sweepergrid(){ for(int i=0; i<numrows; i++){         delete [] grid[i]; } delete [] grid; } 

// function: overloaded assignment operator

void sweepergrid::operator= (sweepergrid const & source){     numrows=source.getrows();     numcolumns=source.getcolumns();     numbombs=source.getbombs();  for(int i=0; i<numrows; i++){     delete [] grid[i]; } delete [] grid;  grid = new sweepercell * [numrows]; for(int i=0; < numrows; i++){     grid[i] = new sweepercell[numcolumns]; }  for(int i=0; i<numrows; i++){     (int j=0; j<numcolumns; j++){         grid[i][j] = source.at(i, j);     } } } 

your problem caused deleting different number of rows allocated:

void sweepergrid::operator= (sweepergrid const & source){     numrows=source.getrows(); // numrows becomes assigned number of rows here.                               // problem, because don't remember how many                               // rows need delete!     numcolumns=source.getcolumns();     numbombs=source.getbombs();      for(int i=0; i<numrows; i++){ // delete rows here, number of rows found in                                   // new grid, not old one.         delete [] grid[i];     }     delete [] grid;  ... } 

a simple fix:

void sweepergrid::operator= (sweepergrid const & source){      for(int i=0; i<numrows; i++){ // delete rows here, while still remember                                    // how many should delete         delete [] grid[i];     }     delete [] grid;     numrows=source.getrows(); // numrows becomes assigned number of rows here.                               // not problem, because don't need                               // remember how many rows need delete.     numcolumns=source.getcolumns();     numbombs=source.getbombs(); ... } 

this sort of issue why manually using delete , new terrible idea--moreover, it's not exception safe (what happen if in constructor, allocating 1 of rows failed after you'd allocated other stuff? you'd lose every piece of memory had allocated in constructor, never seen until shut down program.)

the far easier solution apply resource acquisition is initialization idiom (raii short) , use container controls resources allocating them on construction , deallocating on destruction--a vector you, , nifty things smart pointers. removes responsibility handling every. single. allocation. if. even. a. single. one. fails, because raii, if 1 fails, resources allocated clean themselves up.

as example, here's assignment operator might if using vector of vectors grid, , not c-style dynamic array bunch of c-style dynamic arrays:

void sweepergrid::operator= (sweepergrid const & source){     numrows=source.getrows();      numcolumns=source.getcolumns();     numbombs=source.getbombs();      grid = source.grid; } 

Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -