[英]Realloc produces undefined behavior in C when used with a 2d array
field *field_pointer;
/* Enumerates the whole field by saving the coordinates of the free pieces and the dimensions */
void enum_field(char *filename) {
FILE *maze;
maze = fopen(filename, "r");
int i = 0, j = 0, chr;
field_pointer = (field *)malloc(sizeof(field *));
field_pointer->empty_coords = (int **)malloc(sizeof(int *));
field_pointer->free_spaces = 0;
while ((chr = fgetc(maze)) != EOF) {
if (chr == '\n') {
i = 0;
j++;
} else {
if (chr != '#') {
field_pointer->empty_coords[field_pointer->free_spaces] = (int *)malloc(2 * sizeof(int));
field_pointer->empty_coords[field_pointer->free_spaces][0] = i;
field_pointer->empty_coords[field_pointer->free_spaces][1] = j;
field_pointer->free_spaces++;
// I believe the error is here V
field_pointer->empty_coords = (int **)realloc(field_pointer->empty_coords,
(field_pointer->free_spaces + 1) * sizeof(int *));
if (chr == 'E') {
field_pointer->E[0] = i;
field_pointer->E[1] = j;
} else if (chr == 'S') {
field_pointer->S[0] = i;
field_pointer->S[1] = j;
}
}
i++;
}
}
field_pointer->x = i;
field_pointer->y = j;
fclose(maze);
}
好吧,所以我在这里有这个 C function,它可以帮助我枚举一个 2D ASCII 迷宫,然后我可以把它变成一个图形。 ASCII 迷宫用#
表示墙壁,自由空间表示可步行的道路, S
表示开始, E
表示出口。 function 不起作用并抛出0xC0000374
这可能意味着堆损坏。 我试图进一步调查并注意到很可能,应该扩大二维数组的realloc
function 有问题。 我对 C 比较陌生,并且一直盯着我的代码看,你能帮我用另一个 POV 和新鲜的眼光来看看我可能做错了什么吗? 这也是字段结构的布局:
typedef struct field {
int x, y, free_spaces;
int **empty_coords;
int S[2];
int E[2];
} field;
在您的初始分配中肯定存在大小问题:
field_pointer = (field *)malloc(sizeof(field *))
应该分配结构的大小,而不是指针的大小。 使用field_pointer = malloc(sizeof(field))
或更好:
field_pointer = malloc(sizeof(*field_pointer));
请注意,您可以通过使用真正的 2D 数组而不是指向指向 arrays 的 2 int
的指针数组的指针来简化代码。
另请注意,在完全加载之前,无需操作全局 object。 建议使用局部变量。 返回结构指针允许调用者检测加载迷宫的失败。 存储指向全局变量的指针应该是调用者的责任。
这是修改后的版本:
#include <stdio.h>
#include <stdlib.h>
typedef struct field {
int x, y, free_spaces;
int (*empty_coords)[2];
int S[2];
int E[2];
} field;
field *field_pointer;
/* Enumerates the whole field by saving the coordinates of the free pieces and the dimensions */
field *enum_field(const char *filename) {
FILE *maze = fopen(filename, "r");
if (maze == NULL)
return NULL;
field *fp = calloc(sizeof(*fp), 1);
if (fp == NULL) {
fclose(maze);
return NULL;
}
fp->free_spaces = 0;
fp->empty_coords = NULL;
int i = 0, j = 0, chr;
while ((chr = fgetc(maze)) != EOF) {
if (chr == '\n') {
if (fp->x < i)
fp->x = i;
i = 0;
j++;
} else {
if (chr != '#') {
// allocate space for one extra set of coordinates
int (*new_coords)[2] = realloc(fp->empty_coords,
(fp->free_spaces + 1) * sizeof(*fp->empty_coords));
if (!new_coords) {
free(fp->empty_coords);
free(fp);
fclose(maze);
return NULL;
}
fp = new_coords;
fp->empty_coords[fp->free_spaces][0] = i;
fp->empty_coords[fp->free_spaces][1] = j;
fp->free_spaces++;
if (chr == 'E') {
fp->E[0] = i;
fp->E[1] = j;
} else
if (chr == 'S') {
fp->S[0] = i;
fp->S[1] = j;
}
}
i++;
}
}
fp->y = j;
fclose(maze);
// return structure pointer for the caller to store to into field_pointer
return fp;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.