【问题标题】:Glibc Corrupted Double-Linked List [duplicate]Glibc损坏的双链表[重复]
【发布时间】:2013-12-05 13:36:47
【问题描述】:

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

struct paragraph
{
   char** lines;
   int numLines;
};

struct chapter
{
   struct paragraph** paragraphs;
   int numParagraphs;
};

struct book
{
   struct chapter** chapters;
   int numChapters;
};

这是有问题的代码 sn-p,特别是 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;

在这段代码 sn-p 中调用的函数应该可以正常工作,至少我相信这个事实。这一定是内存管理不善的问题。感谢您的建议!

我应该提一下,它通读了前几章,然后出现了错误。

【问题讨论】:

  • 实际上,我没有看到任何“[双]链表”在哪里..
  • 在 if 语句中执行 realloc 时会出现该错误。阅读前几章后,它似乎内存不足或类似的东西。然而,有趣的注意事项是,完全删除 realloc 语句可以让我的程序读取整个 book.txt 文件,但它并不能正确存储所有内容......根本。
  • 内存管理结构在 realloc() 之前已损坏。在 valgrind 下运行程序。

标签: c struct glibc realloc


【解决方案1】:

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

提供的代码更可能使用数组,而不是列表。因此,如果您尝试使用列表-我在答案的末尾提到了它们。否则,修复它以使用数组更简单,这是第一个问题:

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;

}

如果您有新章节,那么为什么需要重新分配书籍?只需重新分配书籍->章节:

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;
};

当然,需要对“下一个”指针进行适当的分配和分配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-05
    • 2013-11-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2012-02-05
    相关资源
    最近更新 更多