我正在编写一个代码,它将文本文件读取到最大 1024 字节的内存块中。为此,我创建了一个包含 1016 字节数据和指向前一个节点的指针的链表。我的代码完美执行并动态分配和使用数据,并且完美链接回来。当必须创建第四个节点时,问题就出现了。 当我手动增加 malloc 大小(例如将其设置为 1200)时,它会在崩溃之前创建 48 个节点,这表明结构大小增加。但是当我打印 sizeof(*memory) 或 sizeof(struct Chunk) 时,大小仍为 1024 字节。
我收到以下由使用 malloc 的行引起的错误:
malloc.c:2392: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. Aborted (core dumped)
我的代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char **argv) {
// declare variables
int const CHUNK_SIZE = 1024;
int chunk_index = 0;
struct Chunk {
struct Chunk *previous;
int data[(CHUNK_SIZE-sizeof(struct Chunk*))/sizeof(int)];
};
struct Chunk* memory = (struct Chunk *)malloc(sizeof(struct Chunk));
struct Chunk* temp;
// check if the amount of arguments is as expected
if (argc!=2) {
printf("Usage: reverse <filename>\n");
return -1;
}
// check if the file can be opened
FILE *fp;
fp = fopen(argv[1], "r");
if (fp==0) {
printf("Cannot open file!\n");
return -1;
}
// start program
do {
memory->data[chunk_index] = fgetc(fp);
chunk_index++;
if ( chunk_index*sizeof(int) > CHUNK_SIZE-sizeof(struct Chunk*) ) {
temp = (struct Chunk *)malloc(CHUNK_SIZE);
temp->previous = memory;
memory = temp;
}
}
while(memory->data[(chunk_index-1)]!=EOF && chunk_index<CHUNK_SIZE-sizeof(char*));
}
最佳答案
代码在分配新内存时遇到问题,因为它不会重置chunk_index
。最终代码尝试访问外部分配的 memory->data[]
.
int chunk_index = 0;
int ch; // add, last value read
do {
ch = fgetc(fp); // save ch
memory->data[chunk_index] = fgetc(fp);
chunk_index++;
if ( chunk_index*sizeof(int) > CHUNK_SIZE-sizeof(struct Chunk*) ) {
temp = (struct Chunk *)malloc(CHUNK_SIZE);
temp->previous = memory;
memory = temp;
chunk_index = 0; // ** add **
}
}
// ** replace **
// while(memory->data[(chunk_index-1)]!=EOF && chunk_index<CHUNK_SIZE-sizeof(char*));
while(ch !=EOF && chunk_index<CHUNK_SIZE-sizeof(char*));
我怀疑chunk_index<CHUNK_SIZE-sizeof(char*)
是正确的。这可能是不正确的,因为单位不匹配。 chunk_index
索引一个数组(例如,每次 chunk_index
递增时 +4 地址都会改变,但 CHUNK_SIZE-sizeof(char*)
以字节为单位。)OP 将需要检查这一点。我期望while(ch !=EOF);
就足够了。
此外,我会在需要时添加一个新 block 。目前代码将一个新 block 链接到 be prepared下一个fgetc(fp)
,这可能不会发生。通过在 fgetc(fp)
之前添加一个新 block ,代码甚至不需要先前的 memory = (struct Chunk *)malloc(sizeof(struct Chunk));
代码并可以使用 memory = NULL;
提示:不要强制转换并分配给常量,而是放弃强制转换并分配给引用变量的大小。更容易正确编码、审查和维护。
// temp = (struct Chunk *)malloc(CHUNK_SIZE);
temp = malloc(sizeof *temp);
关于c - 奇怪的未知 malloc 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46436068/