glibc detected - double free or corruption
Solution 1
You have to free memory which you have allocated and no longer want to hold a reference too. from your code i can see the following line.
theBoard->_board = newBoard->_board;
Now you maintain reference to a allocated pointer and then free that same pointer itself.
Example code:
char *foo()
{
char *ref1;
char *ref2;
ref1 = malloc(256);
ref2=ref1;// Holding reference to a pointer in another pointer
strcpy(ref1,"stackoverflow");
printf("%s %s",ref1,ref2); // This prints stackoverflow twice
free(ref1); // This is valid but you can access ref2 or ref1 after this point
return ref2; /// This will cause problems
}
Solution 2
Try this:
copyData(theBoard, newBoard);
/* swap the _board pointers */
char * b = theBoard->_board;
theBoard->_board = newBoard->_board;
newBoard->_board = b;
FreeBoard(newBoard); /* cleanup the temp struct and the old array */
Asher Saban
Updated on June 04, 2022Comments
-
Asher Saban almost 2 years
this might be a bit long so my apologies. consider the following code (i've left some irrelevant parts from it). this code receives a pointer to a struct (BoardP theBoard), x & y coords and a value. the goal is to place the value in a 2D array that is found in the struct. if the coords are out of bounds, i have to increase the size of the table, copy old data to new data and place the value in its place. well this code works the first call but in the second call it crashes and writes:
*** glibc detected *** ./b: double free or corruption (top): 0x092ae138 ***
i couldn't find an answer to it and i hope you will help.
These are the calls from main()BoardP p = CreateNewBoard(10,10); PutBoardSquare(p,10,5,'X'); PutBoardSquare(p,5,10,'O'); Boolean PutBoardSquare(BoardP theBoard, int X, int Y, char val) { if (inBounds(X,Y,theBoard->_rows,theBoard->_cols)) { theBoard->_board[X * theBoard->_cols + Y] = val; return TRUE; } else { int newRows = (X>=theBoard->_rows) ? (2*X) : theBoard->_rows; int newCols = (Y>=theBoard->_cols) ? (2*Y) : theBoard->_cols; BoardP newBoard = CreateNewBoard(newCols,newRows); //this creates a new Board with the new dimensions if (newBoard == NULL) { //ReportError(MEM_OUT); return FALSE; } else { copyData(theBoard,newBoard); freeBoardArray(&theBoard->_board[0]); //free old array theBoard->_board = newBoard->_board; //old array point to new array FreeBoard(newBoard); //free the temp copy THIS CAUSES THE PROBLEM PutBoardSquare(theBoard,X,Y,val);//recursion, will be in bounds now return TRUE; } } }
These are the Free functions:
void FreeBoard(BoardP board) { if (board != NULL) { printf("FREE 1\n"); //free the board array: if (board->_board != NULL) { printf("FREE 2\n"); freeBoardArray(&board->_board[0]); printf("FREE 3\n"); } free(board); } } static void freeBoardArray(char * arrP) { free(arrP); //**PROGRAM CRASH HERE** }
This is how i create a new board:
BoardP CreateNewBoard(int width, int high) { BoardP board = (BoardP) malloc(sizeof(Board)); if (board != NULL) { board->_board = allocateBoardArray(high,width); if ( board->_board == NULL) { FreeBoard(board); //TODO make file ReportError(MEM_OUT); return NULL; } initializeBoard(board,high,width,X_SIGN,SPACE); return board; } else { FreeBoard(board); //TODO make file ReportError(MEM_OUT); return NULL; } } static char* allocateBoardArray(int row, int col) { char* newBoard = (char*) malloc(row * col * sizeof(char)); if (newBoard == NULL) { return NULL; } return newBoard; }
this is BoardP:
typedef struct Board* BoardP;