这可能有点长,所以我道歉。 考虑以下代码(我从中留下了一些不相关的部分)。此代码接收指向结构(BoardP theBoard)的指针,x& y coords和value。 目标是将值放在结构中找到的2D数组中。 如果coords超出范围,我必须增加表的大小,将旧数据复制到新数据并将值放在其位置。 以及这个代码在第一次调用时工作,但在第二次调用中它会崩溃并写入:
*** glibc detected *** ./b: double free or corruption (top): 0x092ae138 ***
我找不到答案,希望你会帮忙 这些是来自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;
}
}
}
这些是免费功能:
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**
}
这是我创建新主板的方式:
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;
}
这是BoardP:
typedef struct Board* BoardP;
答案 0 :(得分:6)
您必须释放已分配的内存,并且不再想要保留引用。 从你的代码我可以看到以下行。
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
}
答案 1 :(得分:1)
试试这个:
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 */
答案 2 :(得分:0)
此错误表示您正在尝试释放已经释放的内存。我怀疑的是这段代码
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(&amp; board-&gt; _board [0]);然后你释放整个结构自由(板);,它看起来导致问题。为什么你传递_board指针的地址?我在同一行代码上写了代码,导致问题。< / p>
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;
}
此代码会导致与您显示的问题相同。现在再次尝试删除'&amp;'后的代码来自free(&amp; aptr-&gt; next);声明。它会正常工作。 所以我认为你有一个线索,你必须修改。
答案 3 :(得分:0)
在valgrind下运行此代码将告诉您确切地在哪一行上。)首先释放内存和b。)当您尝试再次释放它时。
它还会告诉您是否尝试访问已释放的块内的任何地址。