我有一个程序可以读取文本文件并将其分为章节和段落结构。
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;
此代码段中调用的函数应该可以正常工作,至少我是依赖于这个事实。这是一个记忆管理不善的问题。谢谢你的建议!
我应该提一下,它会通读前几章,然后就会出错。
答案 0 :(得分: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;
};
当然,需要适当的分配和“下一个”指针的分配。