A Book That Owns Its Title

Hard

Read pairs of a title and a page count until the input runs out, print each book, and give every byte back. Everything except two functions is written for you: main reads with scanf("%31s %d", title, &pages) into one reused buffer, keeps up to four books in an array of pointers, prints the totals, and calls free_book on each one at the end, while print_book shows the shape this lesson asks you to prefer, taking a const struct Book * so that nothing is copied and nothing can be modified by accident. What is missing is make_book and free_book, and between them they are the whole lesson. make_book allocates the struct with malloc(sizeof *book), which is chapter 4's sizing idiom in its full form rather than chapter 5's collapsed malloc(length + 1), and checks the result against NULL before touching it. Then it gives the book a title of its own, because the title it was handed points into main's buffer and that buffer is overwritten by the next scanf: allocate strlen(title) + 1 bytes, the characters plus the terminator that nobody counts, and strcpy into them. Leave the + 1 out and the terminator lands one byte past the end, which is a heap-buffer-overflow with a WRITE and the run ends there. Both allocations get checked, and the second check is the interesting one, since returning NULL at that point without freeing the struct you already have leaks it: clean up what you took before you give up. Reach the members with the arrow, book->title and book->pages, because what you hold is an address and not a struct. free_book undoes all of that and its two rules are order and tolerance. Return immediately when book is NULL, so that a failed make_book can be passed straight to it, and then free the member before the struct, free(book->title); before free(book);, because the other order reads the title pointer out of a block that has already been released, which is a heap-use-after-free rather than a shortcut. fail_on_memory_leak is watching both functions: a book whose title is never freed leaks the string even when every line of output is correct. main returns 0 on every path, including the one that reads nothing at all and prints no books, since the checker treats a nonzero exit status as a failure however correct the printed output looks.

Success Criteria

Your code must pass 5 test case(s) to complete this exercise. 3 hint(s) are available if you need help.

Sign in to track your progress

You can work on exercises as a guest, but sign in to track your progress and save your submissions.

This platform is built by its community

Every lesson, project, and tool on HelloC++ is funded by sponsors. Join them and help shape what we build next.

Become a Patron