malloc:释放对象的校验和不正确 0x7fd4f4c8bbd0:可能在释放后被修改
malloc: Incorrect checksum for freed object 0x7fd4f4c8bbd0: probably modified after being freed
我正在尝试编写一个解析器来导入 OBJ 文件,但即使在这个早期阶段,我在执行时遇到以下错误:
malloc: Incorrect checksum for freed object 0x7fd4f4c8bbd0: probably modified after being freed.
它设法打印每行的缓冲区大小,所以我想知道问题是否与操作后关闭文件有关。
有人能告诉我我做错了什么吗?我在 macOS 运行。
int Utilities_Import_OBJ(const char *filename) {
// input checking
if (filename == NULL) {
printf("Unable to parse file, filename was NULL.\n");
return -1;
}
char *path = strcat(_resource_path, filename);
FILE *file = fopen(path, "r");
if (file == NULL) {
printf("Error opening %s\n", filename);
return -1;
}
// create a line buffer
const int length = 1024;
char buffer[length];
int index = 0;
// fgets stops reading at a \n and appends [=11=]
while (fgets(buffer, sizeof(buffer), file)) {
printf("Buffer size at line %d : %d\n", index, sizeof(buffer));
index++;
}
// done with file, so close it
if (fclose(file) != 0) {
printf("Failed to close file!\n");
return -1;
}
return 0;
}
您的代码中有 2 行令人惊讶:
char *path = strcat(_resource_path, filename);
strcat
不会将 2 个字符串连接成第三个分配的字符串。它在第一个字符串的末尾复制第二个字符串。根据 _resource_path
的分配方式,这一行很可能会破坏 malloc()
内部数据并最终产生问题。你应该像这样写一个特定的函数:
char *concat(const char *s1, const char *s2) {
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
char *p = malloc(len1 + len2 + 1);
if (p) {
memcpy(p, s1, len1);
memcpy(p + len1, s2, len2 + 1);
}
return p;
}
你会 free
使用后 char *path = concat(_resource_path, filename);
返回的字符串。
printf("Buffer size at line %d : %d\n", index, sizeof(buffer));
缓冲区大小是恒定的,sizeof(buffer)
始终计算为 length
在 buffer
定义时的值 (1024)。此外,您应该将 %zu
用于 size_t
参数,而不是 %d
,它需要一个可能具有不同大小的 int
。你可能想这样写:
printf("Buffer length at line %d: %zu\n", index, strlen(buffer));
我正在尝试编写一个解析器来导入 OBJ 文件,但即使在这个早期阶段,我在执行时遇到以下错误:
malloc: Incorrect checksum for freed object 0x7fd4f4c8bbd0: probably modified after being freed.
它设法打印每行的缓冲区大小,所以我想知道问题是否与操作后关闭文件有关。
有人能告诉我我做错了什么吗?我在 macOS 运行。
int Utilities_Import_OBJ(const char *filename) {
// input checking
if (filename == NULL) {
printf("Unable to parse file, filename was NULL.\n");
return -1;
}
char *path = strcat(_resource_path, filename);
FILE *file = fopen(path, "r");
if (file == NULL) {
printf("Error opening %s\n", filename);
return -1;
}
// create a line buffer
const int length = 1024;
char buffer[length];
int index = 0;
// fgets stops reading at a \n and appends [=11=]
while (fgets(buffer, sizeof(buffer), file)) {
printf("Buffer size at line %d : %d\n", index, sizeof(buffer));
index++;
}
// done with file, so close it
if (fclose(file) != 0) {
printf("Failed to close file!\n");
return -1;
}
return 0;
}
您的代码中有 2 行令人惊讶:
char *path = strcat(_resource_path, filename);
strcat
不会将 2 个字符串连接成第三个分配的字符串。它在第一个字符串的末尾复制第二个字符串。根据_resource_path
的分配方式,这一行很可能会破坏malloc()
内部数据并最终产生问题。你应该像这样写一个特定的函数:char *concat(const char *s1, const char *s2) { size_t len1 = strlen(s1); size_t len2 = strlen(s2); char *p = malloc(len1 + len2 + 1); if (p) { memcpy(p, s1, len1); memcpy(p + len1, s2, len2 + 1); } return p; }
你会
free
使用后char *path = concat(_resource_path, filename);
返回的字符串。printf("Buffer size at line %d : %d\n", index, sizeof(buffer));
缓冲区大小是恒定的,
sizeof(buffer)
始终计算为length
在buffer
定义时的值 (1024)。此外,您应该将%zu
用于size_t
参数,而不是%d
,它需要一个可能具有不同大小的int
。你可能想这样写:printf("Buffer length at line %d: %zu\n", index, strlen(buffer));