分配:我们有一个用户可以“绘制”的画布 - 它们可以绘制线条,添加或删除行/列等。我们必须实现的一个命令是调整画布大小。根据分配规范,新行将添加到画布顶部,新行将添加到右侧。这些新行/列填充空格,用'*'表示。用户输入r numRows numCols
。
我正在努力的部分是使用realloc。如果我有一个5x5画布开始,并且用户决定调整大小为7x5,我该怎么做? realloc在哪里放置新的行/列,并自动将现有行向下移动?我有一个函数implementResize,在用户输入r:
时调用void implementResize(BoardState* boardState, int newRows, int newCols) {
if (newRows > boardState->board.numRows) {
printf("add rows\n");
addRow(boardState, newRows);
}
else if (newCols < boardState->board.numRows) {
printf("delete rows\n");
//deleteRow();
}
else {
printf("same\n");
boardState->board.numRows = newRows;
}
if (newCols > boardState->board.numCols) {
printf("add columns\n");
//addCol();
}
else if (newCols < boardState->board.numCols) {
printf("delete columns\n");
//deleteCol();
}
else {
printf("same\n");
boardState->board.numCols = newCols;
}
}
现在我专注于如何在画布顶部添加行。我现在的函数addRow的代码是:
void addRow(BoardState *boardState, int newRows) {
boardState->board.numRows = newRows;
boardState->board.theBoard = (char**) realloc(boardState->board.theBoard, boardState->board.numRows * sizeof(char*));
}
我正在试图弄清楚如何为行重新分配空间。我知道我需要根据newRows的数量和列数使用嵌套的for循环,但我不确定这些新行的位置。如果有人能清除我的困惑,我会很感激。
答案 0 :(得分:0)
此代码无法直接放入您的程序,因为它不使用addColumn
或addRow
。相反,这会让您了解如何解决问题。
在有捕获的行添加了评论。还有一些建议。
int resizeBoard(BoardState *boardState, size_t newRows, size_t newCols) {
//verify before you dereference
if(boardState == NULL)
return 0;
if(boardState->board.theBoard == NULL)
return 0;
const size_t oldRows = boardState->board.numRows; //more readbale
/*
** if the number of rows decreased, free the excess
** we have to do it now because it becomes inaccessible after realloc of boardState.board.theBoard
*/
for(int i = newRows; i < oldRows; i++)
free(boardState->board.theBoard[i]);
/* set these to the new values so that freeBoard gets the correct data in case of failure */
boardState->board.numRows = newRows;
boardState->board.numCols = newCols;
//it is important to use a different pointer to store the value returned by realloc because if the reallocation fails, realloc will return NULL and we will lose access to the original board
void *ptr = realloc(boardState->board.theBoard, izeof(char*)*newRows);
if(ptr == NULL) {
//realloc failed
freeBoard(boardState);
return 0;
}
boardState->board.theBoard = ptr;
//As realloc copies the previous data to the new memory location, theBoard is still pointing to the old rows (from row 0 to row [newRows - 1])
for(int i = 0; i < min(newRows, oldRows); i++) {
void *ptr = realloc(boardState->board.theBoard[i], sizeof(char)*newCols);
if(ptr == NULL) {
//realloc failed
freeBoard(boardState);
return 0;
}
boardState->board.theBoard[i] = ptr;
}
//we cannot use realloc for first time memory allocation; doing so causes undefined behaviour
//we must separately allocate memory for the new rows
for(int i = oldRows; i < newRows; i++)
{
boardState->board.theBoard[i] = malloc(sizeof(char)*newCols);
if(boardState->board.theBoard[i] == NULL) {
//perform cleanup
return 0;
}
}
return 1;
}