C / CHAPTER 12
Allocation and ownership contracts
AdvancedManage 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.
#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;}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