Reputation: 957
I am getting this error (memory location varies between runs):
q2(4910,0x7fff7a1d4300) malloc: *** error for object 0x7fdf79c04bd8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
This is the function that crashes:
public:
// construct a 'rows X cols' matrix.
SMatrix(int rows, int cols) {
if (rows<1 || cols<1) {
cout<<"Invalid row/col value(s).";
exit(-1);
}
this->_rows = rows;
this->_cols = cols;
this->_vertical = new simpleNode [rows];
this->_horizontal = new simpleNode [cols];
if (this->_vertical == NULL || this->_horizontal==NULL) {
cout<<"Exiting";
exit(-1);
}
initArrays();
}
It crashes on this particular line:
this->_horizontal = new simpleNode [cols];
The function that calls:
int main() {
SMatrix bigM(500,500);
bigM.setElement(10,20,17);
cout <<" bigM - total size in bytes: (implementation depended): "
<< bigM.sizeInBytes() << endl << endl;
SMatrix m1(7,10),m2(7,10),m4(10,2),m5(7,2); //Crashes on m4(10,2)
}
Other functions that could be relevant:
struct simpleNode {
Node* _next;
};
int _rows; //Number of rows in this SMatrix
int _cols; //Number of columns in this SMatrix
simpleNode * _vertical; //array (simpleNode)
simpleNode * _horizontal; //array (simpleNode)
/*Initiate the horizontal/vertical arrays to point to null*/
void initArrays() {
int i;
for (i=0; i<this->_rows; i++)
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_vertical[i]._next = NULL;
}
I am on OSX. I compiled with -g and ran it with GDB but Program exited normally. How can I debug this if I don't use XCode? Also a hint on how to fix the problem would be very helpful.
Edit: I'm running the output file and sometimes it runs while others it gives me the error. Seems to be at a random order. Also, the program never fails when I run it on gdb it always exits correctly. Why is this happening?
Upvotes: 6
Views: 17257
Reputation: 66234
Your limits are reversed in your initialization code. You create your arrays like this:
this->_vertical = new simpleNode [rows]; // <== uses rows for sizing vertical
this->_horizontal = new simpleNode [cols]; // <== uses cols for sizing horizontal
But your initialization does this:
for (i=0; i<this->_rows; i++) // <== limit is rows, but you walking horizontal
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++) // <== limit is cols, but you walking vertical
this->_vertical[i]._next = NULL;
Unless rows
and cols
are the same value, this code invokes undefined behavior. Fix this by using the same values as you sized your allocation with
for (i=0; i<this->_rows; i++)
this->_vertical[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_horizontal[i]._next = NULL;
Honestly a much better approach would use RAII containers such as std::vector<>
, but I leave that as an exercise for you.
Best of luck, and hope it helps.
Upvotes: 10
Reputation: 73384
Since you're in the debugger, you should look at the memory location 0x7fff7a1d4300
and see what's there. The data in memory may be helpful in figuring out what's going wrong.
What's happening is one of the following:
you are freeing an object twice,
you are freeing a pointer that was never allocated
you are writing through an invalid pointer which previously pointed to an object which was already freed
I think what happens is No.3.
My answer is based in this answer.
A relevant discussion lies here.
Relevant question about gdb.
Upvotes: 0