Glibc detected - double free or corrupt

It might be a little longer, so I'm sorry. consider the following code (I left some irrelevant parts from it). this code gets a pointer to the structure (BoardP theBoard), x and y coordinates and value. the goal is to put the value in a 2D array that is in the structure. if the coordinates are outside the borders, I need to increase the size of the table, copy the old data to the new data and put the value in its place. Well, this code works with the first call, but in the second call it fails and writes:

*** glibc detected *** ./b: double free or corruption (top): 0x092ae138 ***  

I could not find the answer to it, and I hope you help.
These are 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 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;
+3
4

, , . .

theBoard->_board = newBoard->_board;

, .

:

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
}
+6

:

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 */
+1

, , . ,

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);

freeBoardArray (& board → _ board [0]); (board), , . _board? , .

struct a{
    int * next;

}; int main() {

    struct a *aptr = (struct a *)malloc(sizeof(struct a));
    aptr->next=(int *)malloc(5*sizeof(int));
    free(&aptr->next);
    free(aptr);
    return 0;

}

, . '&' (& aptr- > next); statement.It . , , .

0

Running this code under valgrind will tell you exactly which line you.) First freed memory, and b.) When you tried to free it again.

He will also tell you if you are trying to access any addresses inside the freed block.

0
source

Source: https://habr.com/ru/post/1762047/


All Articles