c-Glibc损坏的双链接列表



我有一个程序可以读取文本文件,并将其分为章节和段落结构。

struct paragraph
{
   char** lines;
   int numLines;
};
struct chapter
{
   struct paragraph** paragraphs;
   int numParagraphs;
};
struct book
{
   struct chapter** chapters;
   int numChapters;
};

以下是有问题的代码片段,特别是realloc()语句:

//int numChapters = -1;
//char**** book = (void*)0;
struct book* books = malloc(sizeof(struct book*));
books->chapters = malloc(sizeof(struct chapter));
books->numChapters = -1;
//char*** nextChapter;
struct chapter* nextChapter = malloc(sizeof(struct chapter));

while ( (nextChapter = readChapter(bookFile))->paragraphs[0] )
{
    if (++(books->numChapters) > 0)
    {
        books = realloc(books, sizeof(struct chapter*)*books->numChapters);
        books->chapters[books->numChapters - 1] = nextChapter;
    }
}
books = realloc(books, sizeof(struct chapter*)*books->numChapters);
books->chapters[books->numChapters] = (void*)0;
return books;

这个代码片段中调用的函数应该可以正常工作,至少我相信这一点。这一定是记忆管理不善的问题。谢谢你的建议!

我应该提到的是,它通读了前几章,然后出现了错误。

也许您不需要在每个结构中使用两个指针?你有用于章节和段落的数组-不需要使用双指针。

提供的代码更有可能使用数组,而不是列表。所以,若你们试图使用列表,我在答案的末尾提到了它们。否则,修复它以使用数组会更简单,这是第一个问题:

if (++(books->numChapters) > 0)
{
    /* here books are reallocated */
    books = realloc(books, sizeof(struct chapter*)*books->numChapters);
    /* but here chapters which had not been reallocated are acessed */
    books->chapters[books->numChapters - 1] = nextChapter;
}

如果你有新的章节,为什么你需要重新分配书籍?只是realloc书籍->章节:

if (++(books->numChapters) > 0)
{
    books->chapters = realloc(books->chapters, sizeof(struct chapter*)*books->numChapters);
    books->chapters[books->numChapters - 1] = nextChapter;
}

最后还是同样的问题:

/* books are reallocated, size is bad - reallocated to size of numChapters * (pointer size) */
books = realloc(books, sizeof(struct chapter*)*books->numChapters);
/* perhaps access to non-allocated memory here */
books->chapters[books->numChapters] = (void*)0;

应为:

books->chapters = realloc(books->chapters, sizeof(struct chapter)*books->numChapters);
// books->chapters[books->numChapters] = (void*)0;

不需要为最后一个元素指定NULL,因为章节的大小为numChapters,而访问元素numChapters会导致访问未分配的内存,崩溃。

上面的所有代码都使用了数组的概念,而不是链表。

要将其切换到链表,需要使用以下结构:

struct paragraph
{
   struct paragraph *next; // <<-- this field is used to build
                           //      linked list of paragraphs
   char* lines;
   int numLines;
};
struct chapter
{
   struct chapter *next; // <<-- this field is used to build 
                         //      linked list of chapters
   struct paragraph* paragraphs;
   int numParagraphs;
};
struct book
{
   struct chapter* chapters;
   int numChapters;
};

当然,需要适当的分配和分配"下一个"指针。

最新更新