liveBook · Manning

Resource cleanup

As explained in Modern C, Third Edition

Cleanup is the release or restoration of resources and state needed when an operation completes or fails.

Resource cleanup releases allocated memory and restores execution state when an operation succeeds, fails, or terminates. Robust C functions preserve errno when reporting errors and ensure that acquired resources are not abandoned. section 15.6

One cleanup path for several failures

A number-printing function allocates a buffer, may enlarge it with realloc, and can fail because allocation, size limits, or output operations fail. The optimized version routes failures to a shared CLEANUP label, where the allocated buffer is released. This keeps free reachable even when an output or reallocation error occurs. Saving errno on entry and restoring it through error_cleanup prevents intermediate operations from changing the reported error state. section 15.6

Reliable cleanup follows explicit rules:

  • Save global error state before operations that might modify it, and restore errno while returning the failure code. section 15.6
  • Free successfully allocated memory on every error path, including failures detected after output or buffer growth. section 15.6
  • Use a common cleanup block when several later operations can fail and each must release the same resources. section 15.6
  • Prefer normal return or exit so the runtime can perform established library cleanups; reserve alternative termination functions for cases that require bypassing them. section 8.8
void sayGoodBye(void) {
  if (errno) perror("terminating with error condition");
  fputs("Good Bye\n", stderr);
}

int main(int argc, char* argv[argc+1]) {
  atexit(sayGoodBye);
  ...
}

An atexit handler can perform termination cleanup, such as freeing memory or writing a final log timestamp, after normal program completion. section 8.8

How Modern C, Third Edition covers it

How deep it goes
Works through allocation, reallocation, output failure, centralized goto cleanup, errno restoration, and atexit handlers.
Examples
Uses number-printing functions, malloc and realloc failures, fputs errors, error_cleanup, goto, and an atexit greeting handler.
What it assumes
Assumes C functions, dynamic allocation, errno, and control flow, while demonstrating cleanup mechanics through concrete examples.
What you can do after
Apply centralized cleanup to C error paths and register termination handlers with atexit when appropriate.
How it connects
Connects error handling with errno, dynamic memory allocation, realloc, program termination, and exit handlers.

Also explained in

Compare how 6 books explain resource cleanup →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.