Problem with delete

Started by
8 comments, last by Nanashi 17 years, 9 months ago
Well, I wasn't exactly sure if this was the correct forum, but since I guess I'm a "beginner" I'll put it in here. On to the problem then. CBoard::~CBoard( ) { // Deletes the array of SSquares from memory delete[] mySquares; } This is throwing a run-time error. It compiles fine, but whenever I run the program this causes a problem, but whenever I comment it out, the program runs without a hitch. mySquares is an array of SSQUARES (a struct). It is set up like this is the constructor: CBoard::CBoard( ) { // Creates a matrix 9 squares large, to use as a 3x3 grid. mySquares = new SSQUARE[9]; and is created privately like this in the class: class CBoard { private: SSQUARE *mySquares; To be honest, I would swear I was deallocating the memory correctly. Anyone have any ideas?
Advertisement
Looks like you are trying to delete a variable that it does not have access to. Your destructor needs to delete the internal variables that it has declared using new, not external ones that you declare.
------------------This is so stupid!
Quote:Original post by -JetSirus-
Looks like you are trying to delete a variable that it does not have access to. Your destructor needs to delete the internal variables that it has declared using new, not external ones that you declare.


Ah sorry, actually the SSQUARE *mySquares declaration is in the private section of the same class. I thought that member functions of classes had access to private variables, so this technically should work I would think.
I'm not 100% sure, but I think this happens when you try to delete something that isn't yours. Whatever mySquares is pointing to at the end, it is probably not the same thing it used to point to when you initialized it. Somewhere in your code, you probably, intentionally or not, changed what mySquares points to.

My only other idea is that perhaps it's because you didn't clear out the memory when you intitialized mySquares. You know how good reference manuals teach you to declare pointers like this: int* pMyIntPointer = NULL;. Perhaps it's the same idea here. Except since it's an array, you would have to do it with a loop:

for( unsigned int i = 0; i < 9; ++i ) mySquares = NULL;</tt><br><br>Good luck [smile]
.:<<-v0d[KA]->>:.
It works now... I'm so confused... I'm not sure what I changed in the process...
Don't you just love CPP for that? :p
------------------This is so stupid!
Pointers are freaky things. They're certainly not binary in nature. They either totally work, completely don't work, work some of the time but not others, appear to work while in fact you are leaking memory megabytes at a time, work only during a full moon, etc...

So to truly make sure you properly deallocate memory, you should get your development environment to report memory leaks. If you're using Visual Studio, I found this: http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=63847
Just add a couple lines to your code, and when you exit, Visual Studio should report any memory leaks in the output window.
.:<<-v0d[KA]->>:.
Chances are good that you had some code somewhere else in the program that would write past the bounds of an array, corrupting the little bit of tag data that indicated the size of the mySquares and thus causing the deletion to blow up.
I suspect that this is a copy-constructor issue, although the problem appears to have gone I thought you might like to know what may have been happening.

Take the CBoard class as you described it:

class CBoard{private:    SSQUARE* m_mySquares;public:    CBoard()    {        m_mySquares = new SSQUARE[9];    }    ~CBoard()    {        delete [] m_mySquares;    }};


and use it in the following context:

void UseBoard(CBoard _board){    // doing something with the board that was passed by value}int main(int argc, char* _argv[]){    CBoard myBoard;    UseBoard(myBoard);    return 0;}


Looks quite innocent, doesn't it? But this will produce the same result that you described. But why? Well, remember that when you pass a class by value to a function the temporary variable (in this case _board) is created using the copy-constructor of the CBoard class, which unless you tell it otherwise will create an exact copy of the object you passed.

What this means is that when the UseBoard function ends _board is destroyed which deletes the m_mySquares pointer, but because _board is an exact copy of myBoard their m_mySquares pointers are pointing to the same memory location. However myBoard is blissfully unaware of this and so when it comes to being destroyed it happily tries to free the memory pointed to by m_mySquares and you are treated to a run-time error.

You could overcome this by passing to functions by reference.
Quote:Original post by MrP
I suspect that this is a copy-constructor issue, although the problem appears to have gone I thought you might like to know what may have been happening.

Take the CBoard class as you described it:

*** Source Snippet Removed ***

and use it in the following context:

*** Source Snippet Removed ***

Looks quite innocent, doesn't it? But this will produce the same result that you described. But why? Well, remember that when you pass a class by value to a function the temporary variable (in this case _board) is created using the copy-constructor of the CBoard class, which unless you tell it otherwise will create an exact copy of the object you passed.

What this means is that when the UseBoard function ends _board is destroyed which deletes the m_mySquares pointer, but because _board is an exact copy of myBoard their m_mySquares pointers are pointing to the same memory location. However myBoard is blissfully unaware of this and so when it comes to being destroyed it happily tries to free the memory pointed to by m_mySquares and you are treated to a run-time error.

You could overcome this by passing to functions by reference.


Awesome, I believe this is what it was. Thanks for the explanation!

This topic is closed to new replies.

Advertisement