正在尝试重新分配结构,c

正在尝试重新分配结构,c,c,struct,C,Struct,我一直在努力创建一个董事会。 以下是董事会的结构: typedef struct Board { int width; int height; char **board; } Board; static BoardP expandBoard(BoardP theBoard, int X, int Y) { int newWidth = theBoard->width; int newHeight = theBoard->height;

我一直在努力创建一个董事会。 以下是董事会的结构:

typedef struct Board
{
    int width;
    int height;
    char **board;
} Board;
static BoardP expandBoard(BoardP theBoard, int X, int Y)
{
    int newWidth = theBoard->width;
    int newHeight = theBoard->height;
    if (X>theBoard->height)
    {
        newHeight = (newHeight+1) * 2;
    }

    if (Y>theBoard->width)
    {
        newWidth = (newWidth+1) * 2;
    }

    BoardP result = createNewBoard(newWidth,newHeight);

    int i;
    for (i=0; i<newHeight; i++)
    {
        result->board[i] = realloc(theBoard->board[i],newWidth);
    }

    freeBoard(theBoard);
    return result;
}
这是返回指向Board(BoardP)指针的构造函数:

BoardP createNewBoard(int-width,int-high)
{
BoardP board=(BoardP)malloc(sizeof(board));
如果(线路板==NULL)
{
报告错误(MEM_OUT);
返回NULL;
}
板->高度=高;
板->宽度=宽度;
线路板->线路板=(字符**)malloc(高*尺寸)(字符*);
int i;
对于(i=0;iboard[i]=(char*)malloc(width*sizeof(char));
}
如果(线路板->线路板==NULL)
{
//我应该单独释放每条线吗??!!??!
免费(膳宿);
报告错误(MEM_OUT);
返回NULL;
}
返回板;
}
下面是我扩大董事会的尝试:

typedef struct Board
{
    int width;
    int height;
    char **board;
} Board;
static BoardP expandBoard(BoardP theBoard, int X, int Y)
{
    int newWidth = theBoard->width;
    int newHeight = theBoard->height;
    if (X>theBoard->height)
    {
        newHeight = (newHeight+1) * 2;
    }

    if (Y>theBoard->width)
    {
        newWidth = (newWidth+1) * 2;
    }

    BoardP result = createNewBoard(newWidth,newHeight);

    int i;
    for (i=0; i<newHeight; i++)
    {
        result->board[i] = realloc(theBoard->board[i],newWidth);
    }

    freeBoard(theBoard);
    return result;
}
static BoardP expandBoard(BoardP theBoard,int X,int Y)
{
int newWidth=电路板->宽度;
int newHeight=theBoard->height;
如果(X>theBoard->高度)
{
新高度=(新高度+1)*2;
}
如果(Y>电路板->宽度)
{
新宽度=(新宽度+1)*2;
}
BoardP结果=createNewBoard(新宽度、新高度);
int i;
对于(i=0;iboard[i]=realloc(theBoard->board[i],newWidth);
}
干舷(底舷);
返回结果;
}
但我一直在犯分割错误,我不知道为什么。我的基本想法正确吗?
知道我做错了什么吗?谢谢

首先,您需要检查每一行(当它在for循环中被malloc分配时)没有失败。您已经检查了
board->board
,但没有检查每一行,这也是
malloc
'd,必须检查它们是否正确分配。否则,该板的一行可能为空,当尝试使用
realloc
时,它将收到一个空指针。

看起来像您因为您将新板的行指向旧板的重新分配内存,然后释放旧板,所以出现分段错误。我不确定您为什么要在
createNewBoard
函数中为新板分配内存的情况下执行realloc操作。

这里有很多可能的错误。请确保创建一个不透明的数据结构,就像您编写帮助器函数那样,让您的生活更轻松,然后使用这些帮助器

我已将您的代码调整为一个带有存根驱动程序的小型工作示例程序。让我详细介绍一下:

#include <stdio.h>
#include <stdlib.h>

#DEFINE BOARD_BLANK ' '

typedef struct Board 
{
    int width;
    int height;
    char **board;
} Board;

typedef Board *BoardP;

#define MEM_OUT 109

void reportError(int msg)
{
    // Stub
}
请注意注释!当您调用修改并返回指针的函数时,请确保执行赋值。否则,您仍将指向旧的自由对象,这对您没有好处

或者,您可以始终将指针传递给修改指针的函数的指针


无论如何,我希望这能有所帮助。小心!

你需要缩小到导致segfault的代码部分(理想情况下是一行)。你在哪一行出现了分段错误?我怎么知道?它只说“分段错误”@yotamo:请不要将问题添加为对答案的编辑。或者添加注释(如果它确实与此答案相关),将它们添加到您的问题中(如果它只是此问题的扩展),或提出一个新问题。
BoardP createNewBoard(int width, int height)
{
    BoardP board = (BoardP) malloc(sizeof(Board));

    if (board == NULL) 
        goto err1; // Error, jump to alternative error handling exit

    board->height = height;
    board->width = width;
    board->board = (char**) malloc(height* sizeof(char*));

    if (board->board == NULL) 
        goto err2; // Error, jump to alternative error handling exit

    int i;
    for (i=0; i<height; i++)
    {
        // Allocate each row one at a time
        board->board[i] = (char*) malloc(width * sizeof(char));
        if (board == NULL)
            goto err3; 
        for (j=0; j<height; j++)
            board->board[i][j] = BOARD_BLANK; // Give all the data points an initial value
    }

    // Successfully allocated board -- return it.
    return board;

    // Error handling code
err3:
    while (i-- > 0) // Start freeing rows from where we left off
        free(board->board[i]);
    free(board->board); // Free the allocated board->board too

err2:
    free(board);
err1:
    reportError(MEM_OUT);
    return NULL;
}
BoardP expandBoard(BoardP board, int X, int Y)
{
    int newWidth = board->width;
    int newHeight = board->height;
    if (X > board->height) // This seems backwards. Height is usually in terms of Y
        newHeight = (newHeight+1)*2; // If we're trying to ensure that the new board
                                     // can contain X as a row index, then it should be:
                                     // newHeight = (board->height > X) ? board->height : X;

    if (Y > board->width) // Same here; width is usually in terms of X
        newWidth = (newWidth+1)*2; // Likewise, should this be:
                                   // newWidth = (board->width > Y) ? board->width : Y; 

    // Create a new board using the constructor we already wrote
    BoardP newBoard = createNewBoard(newWidth, newHeight);

    int i, j;
    for (i=0; i<newHeight; i++) 
        for (j=0; j<board->width; j++)
            newBoard->board[i][j] = board->board[i][j]; // Simply copy data from old to new

    freeBoard(board); // Free the old board
    return newBoard;
}
int main()
{
    BoardP board = createNewBoard(50, 50);
    board = expandBoard(board, 3, 2); // Make sure you assign the board pointer to
                                      // the new expanded board!
    freeBoard(board);

    return 0;
}