C / CHAPTER 12

Allocation and ownership contracts

Advanced

Manage an allocated object through every success and failure path.

By the end of this chapter

  • Check allocation before using memory
  • Initialize allocated storage
  • Release each owned allocation exactly once

The idea

Enter with pointers and object lifetime understood. Dynamic allocation is useful when an object’s lifetime must outlast the block that creates it. malloc reserves a requested number of bytes and returns either a pointer or NULL. The storage does not arrive with useful int values already initialized. Size the allocation from the pointed-to type, check success, and initialize before reading.

Ownership is a program contract, not a property carried by a raw pointer. Decide which function must eventually call free and document any borrowed pointers that must not free the same object. After freeing storage, neither its former owner nor an alias may access that object. For arrays, also check that count times element size cannot overflow before allocation. Cleanup paths deserve the same care as the successful path.

C example
#include <stdio.h>
#include <stdlib.h>
int main(void){int *value=malloc(sizeof *value); if(value==NULL)return 1;
 *value=21; printf("%d\n",*value); free(value); return 0;}
Result
21 (if allocation succeeds; otherwise no output and exit status 1)

The pointer is checked before dereferencing, the int is initialized, and the allocation is released exactly once after its final use.

Try it yourself

Describe ownership for a function that returns a newly allocated struct, including the caller’s cleanup responsibility.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

What must happen before reading an int from successful malloc storage?