面试题:C语言结构体指针数组内存释放的复杂情况
有如下复杂结构体定义:
```c
struct Book {
char title[50];
char author[30];
struct Book *next;
};
```
通过以下方式创建了一个结构体指针数组并进行了一些链表关联操作:
```c
struct Book **books = (struct Book **)malloc(3 * sizeof(struct Book *));
for (int i = 0; i < 3; i++) {
books[i] = (struct Book *)malloc(sizeof(struct Book));
sprintf(books[i]->title, "Book%d", i + 1);
sprintf(books[i]->author, "Author%d", i + 1);
if (i < 2) {
books[i]->next = books[i + 1];
} else {
books[i]->next = NULL;
}
}
```
请编写函数 `freeBooks` 来正确释放 `books` 数组及其关联链表所占用的所有内存,要求考虑内存释放顺序和防止内存泄漏。