我有一个程序可以读取文本文件,并将其分为章节和段落结构。
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;
};
当然,需要适当的分配和分配"下一个"指针。