我在使用realloc
功能时遇到了一些问题。
我正在使用此函数分配动态二维数组:
Bubble ***allocBubblesMatrix(int height, int width) {
Bubble ***bubblesMatrix = (Bubble***) malloc(height * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (Bubble**) malloc(width * sizeof(Bubble*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = newBubble(rand() % N_BUBBLES);
return bubblesMatrix;
}
用下一个代码调用:
int matrixHeight = 1,
matrixWidth = MATRIX_X_SIZE;
Bubble ***bubblesMatrix = allocBubblesMatrix(matrixHeight, matrixWidth);
这成功地创建了一个二维数组1 * MATRIX_X_SIZE。
然后,我想在矩阵中添加一行或多行,因此我使用realloc
和以下函数。它应该添加heightIncrement
行。问题在于,有时它会起作用,而其他程序则会崩溃。
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (Bubble***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (Bubble**) malloc(width * sizeof(Bubble*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
}
使用以下函数调用此函数:
while(true) {
drawBubblesMatrix(x1, y1, matrixHeight, matrixWidth, &bubblesMatrix, bubbles);
resizeBubblesMatrix(&bubblesMatrix, matrixHeight, matrixWidth, 1);
++matrixHeight;
getch();
clear_screen(1);
}
我做错了什么?
解除分配先前分配的内存块的功能:
void freeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width) {
int y, x;
for (y = 0; y < height; ++y) {
for (x = 0; x < width; ++x) {
free((*bubblesMatrix)[y][x]);
(*bubblesMatrix)[y][x] = NULL;
}
free((*bubblesMatrix)[y]);
(*bubblesMatrix)[y] = NULL;
}
free(*bubblesMatrix);
*bubblesMatrix = NULL;
}
提前致谢。
修改
realloc
的返回值做任何事情。但是现在每当我运行程序时程序都会崩溃。assert
来检查malloc
/ realloc
来电的结果,但我没有运气。我正在使用带有Win98的djgpp,它发生了什么真的很奇怪:
答案 0 :(得分:3)
该函数可以将存储块移动到新位置,在这种情况下返回新位置....指向重新分配的存储块的指针,该指针可以与ptr参数或新位置相同。 此指针的类型为void *,可以将其强制转换为所需类型的数据指针,以便可以取消引用。 如果函数未能分配请求的内存块,则返回NULL指针,并且参数ptr指向的内存块保持不变。
如果不对返回值执行某些操作,则无法正确使用realloc
。您的代码现在希望realloc
始终能够以新块在同一位置的方式重新分配内存。这显然是不可能的;你的阵列可能正在使用其他东西之后的内存。
答案 1 :(得分:3)
使用realloc
时出现了许多问题。
realloc
。你应该传递你从malloc
获得的指针,它将是*bubblesMatrix
。 allocBubblesMatrix
和resizeBubblesMatrix
函数中矩阵的“布局”不同。在alloc函数中,您分配了几个独立的内存块,但在resize函数中,您将其视为一个大的内存块。这根本行不通。正确的用法是:
void resizeBubblesMatrix(Bubble ****bubblesMatrix, int height, int width,
int heightIncrement) {
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));
int i;
int newHeight = height + heightIncrement;
for (i = height; i < newHeight; ++i)
(*bubblesMatrix)[i] = (Bubble**) malloc(width * sizeof(Bubble*));
int x, y;
for (y = height; y < newHeight; ++y)
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = newBubble(rand() % N_BUBBLES);
}
但是这个功能仍有一些问题:
malloc
和realloc
都可能失败,此处未予考虑heightIncrement
为负数,则调整大小函数中会出现内存泄漏。答案 2 :(得分:2)
我汇总了一个快速测试用例,我得出的结论是,您现在遇到的问题不在于此代码块。我创建了一个非常简单的测试用例,用int替换Bubble对象。当我这样做时,重新分配成功完成而不会崩溃。这是我的代码:
#include <malloc.h>
#include <assert.h>
int myVal = 0xDEAD;
int ***allocBubblesMatrix(int height, int width);
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement);
int main(int argc, char **argv)
{
int matrixHeight = 1, matrixWidth = 10;
int i = 0;
int ***matrix = allocBubblesMatrix(matrixHeight, matrixWidth);
for(i = 1; i < matrixWidth; i++)
resizeBubblesMatrix(&matrix, matrixHeight, matrixWidth, 1);
printf("Complete!\n");
}
int ***allocBubblesMatrix(int height, int width) {
int ***bubblesMatrix = (int***) malloc(height * sizeof(int**));
assert(bubblesMatrix != NULL);
int i;
for (i = 0; i < height; ++i) {
bubblesMatrix[i] = (int**) malloc(width * sizeof(int*));
assert(bubblesMatrix[i] != NULL);
}
int x, y;
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
bubblesMatrix[y][x] = &myVal;
return bubblesMatrix;
}
void resizeBubblesMatrix(int ****bubblesMatrix, int height, int width,
int heightIncrement) {
if (heightIncrement <= 0) /* temporary */
return;
*bubblesMatrix = (int***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(int**));
assert(bubblesMatrix != NULL);
int x, y;
int newHeight = height + heightIncrement;
for (y = height; y < newHeight; ++y) {
(*bubblesMatrix)[y] = (int**) malloc(width * sizeof(int*));
assert((*bubblesMatrix)[y] != NULL);
for (x = 0; x < width; ++x)
(*bubblesMatrix)[y][x] = &myVal;
}
}
我所做的唯一更改是用String替换Bubble,并将矩阵中的所有条目指向单个int变量,而不是进行更多的分配。
这意味着错误发生在drawBubblesMatrix()或newBubble()中。
答案 3 :(得分:1)
您需要单独重新分配每个维度。您不能一次重新分配这两个维度,因为每个“行”都是单独分配的。
*bubblesMatrix = (Bubble ***) realloc(bubblesMatrix, (height + heightIncrement) * width * sizeof(Bubble*));
需要改为
*bubblesMatrix = (Bubble ***) realloc(*bubblesMatrix, (height + heightIncrement) * sizeof(Bubble**));