Manual memory management

Short description: Computer memory management methodology

This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages)

This article relies largely or entirely on a single source. Please help improve this article by introducing citations to additional sources.
Find sources: "Manual memory management" – news · newspapers · books · scholar · JSTOR (June 2009)

|

Template:Only primary sources

This article includes a list of references, but its sources remain unclear because it has insufficient inline citations. Please help to improve this article by introducing more precise citations. (July 2018) (Learn how and when to remove this template message)

|

(Learn how and when to remove this template message)

In computer science, manual memory management refers to the usage of manual instructions by the programmer to identify and deallocate unused objects, or garbage. Up until the mid-1990s, the majority of programming languages used in industry supported manual memory management, though garbage collection has existed since 1959, when it was introduced with Lisp.[1] Today, however, languages with garbage collection such as Java are increasingly popular and the languages Objective-C and Swift provide similar functionality through Automatic Reference Counting. The main manually managed languages still in widespread use today are C and C++ – see C dynamic memory allocation.

## Contents

* 1 Description
* 2 Manual memory management techniques
* 3 Manual management and correctness
* 4 Resource acquisition is initialization
* 5 Defer
* 5.1 C
* 5.2 Go
* 5.3 Zig
* 6 Performance
* 7 See also
* 8 References
* 9 External links

## Description

Many programming languages use manual techniques to determine when to allocate a new object from the free store. C uses the `malloc` function; C++ and Java use the `new` operator; and many other languages (such as Python) allocate all objects from the free store. Determining when an object ought to be created (object creation) is generally trivial and unproblematic, though techniques such as object pools mean an object may be created before immediate use. The real challenge is object destruction – determination of when an object is no longer needed (i.e. is garbage), and arranging for its underlying storage to be returned to the free store for re-use. In manual memory allocation, this is also specified manually by the programmer; via functions such as `free()` in C, or the `delete` operator in C++ – this contrasts with automatic destruction of objects held in automatic variables, notably (non-static) local variables of functions, which are destroyed at the end of their scope in C and C++.

## Manual memory management techniques

For example:

* malloc() and free() or new and delete
* Memory arena
* Scratch buffer
* Resource acquisition is initialization, the pattern of tying an object's ownership of resources to its lifetime
* Defer, the act of deferring or postponing cleanup until the end of a function call

## Manual management and correctness

Main article: Memory safety

Manual memory management is known to enable several major classes of bugs into a program when used incorrectly, notably violations of memory safety or memory leaks. These are a significant source of security bugs.[2]

* When an unused object is never released back to the free store, this is known as a memory leak. In some cases, memory leaks may be tolerable, such as a program which "leaks" a bounded amount of memory over its lifetime, or a short-running program which relies on an operating system to deallocate its resources when it terminates. However, in many cases memory leaks occur in long-running programs, and in such cases an unbounded amount of memory is leaked. When this occurs, the size of the available free store continues to decrease over time; when it is finally exhausted, the program then crashes.
* Catastrophic failure of the dynamic memory management system may result when an object's backing memory is deleted out from under it more than once; an object is explicitly destroyed more than once; when, while using a pointer to manipulate an object not allocated on the free store, a programmer attempts to release said pointer's target object's backing memory; or when, while manipulating an object via a pointer to another, arbitrary area of memory managed by an unknown external task, thread, or process, a programmer corrupts that object's state, possibly in such a way as to write outside of its bounds and corrupt its memory management data. The result of such actions can include heap corruption, premature destruction of a different (and newly created) object which happens to occupy the same location in memory as the multiply deleted object, program crashes due to a segmentation fault (violation of memory protection) and other forms of undefined behavior.
* Pointers to deleted objects become wild pointers if used post-deletion; attempting to use such pointers can result in difficult-to-diagnose bugs.

Languages which exclusively use garbage collection are known to avoid the last two classes of defects. Memory leaks can still occur (and bounded leaks frequently occur with generational or conservative garbage collection), but are generally less severe than memory leaks in manual systems.

## Resource acquisition is initialization

Main article: Resource acquisition is initialization

Manual memory management has one correctness advantage, which is that it allows automatic resource management via the resource acquisition is initialization (RAII) paradigm.

This arises when objects own scarce system resources (like graphics resources, file handles, or database connections) which must be relinquished when an object is destroyed – when the lifetime of the resource ownership should be tied to the lifetime of the object. Languages with manual management can arrange this by acquiring the resource during object initialization (in the constructor), and releasing during object destruction (in the destructor), which occurs at a precise time. This is known as Resource Acquisition Is Initialization (RAII).

This can also be used with deterministic reference counting. In C++, this ability is put to further use to automate memory deallocation within an otherwise-manual framework, use of smart pointers in the language's standard library to perform memory management is a common paradigm. In languages like Rust which enforce strict ownership, RAII becomes the default behavior for managing resources.[3]

This approach is not usable in most garbage collected languages – notably tracing garbage collectors or more advanced reference counting – due to finalization being non-deterministic, and sometimes not occurring at all. That is, it is difficult to define (or determine) when or if a finalizer method might be called; this is commonly known as the finalizer problem. Java and other languages implementing a garbage collector frequently use manual management for scarce system resources besides memory via the dispose pattern: any object which manages resources is expected to implement the `dispose()` method, which releases any such resources and marks the object as inactive. Programmers are expected to invoke `dispose()` manually as appropriate to prevent "leaking" of scarce graphics resources. For stack resources (resources acquired and released within a single block of code), this can be automated by various language constructs, such as Python's `with`, C#'s `using`-with-resources (which call an object's `Dispose()` method) or Java's `try`-with-resources (usable on any object which implements `java.lang.AutoCloseable` and calls its `close()` method).

## Defer

A defer mechanism is a feature that allows the postponing of execution of a piece of code until later, usually either the end of scope or end of a function. This can be seen as similar to a finally block in other languages.

### C

C (beginning in C29) introduces a `defer` mechanism. A `defer` block happens only execution reaches it, and executes in reverse order. It runs on scope exit.[4]

#include <stddefer.h>
#include <stdio.h>
#include <stdlib.h>

int processFile(const char path[]) {
FILE* f = fopen(path, "r");
if (!f) {
return -1;

defer {
printf("Closing file.\n");
fclose(f);

char* buffer = malloc(1024);
if (!buffer) {
return -2;

defer {
printf("Freeing buffer.\n");
free(buffer);

// Simulate multiple early exits
if (fgets(buffer, 1024, f)) {
return -3; // both defers still run

if (buffer[0] == '#') {
return -4; // both defers still run

printf("Processing: %s\n", buffer);
return 0;

C++ has not yet commented on whether or not it will integrate C `defer`, as RAII covers this use case.

### Go

In Go, `defer` is used to schedule a function call to run when the surrounding function returns. Multiple `defer`s run in last-in-first-out (LIFO) order.

package main

import "fmt"

func main() {
fmt.Println("start")

defer fmt.Println("first defer")
defer fmt.Println("second defer")

fmt.Println("end")

### Zig

In Zig, `defer` is block-level and runs when the current scope ends, not just the function. Unlike Go, Zig `defer` incurs no overhead.

const std = @import("std");

pub fn main() void {
std.debug.print("start\n", .{});

defer std.debug.print("inner defer\n", .{});
std.debug.print("inside block\n", .{});

std.debug.print("end\n", .{});

Zig also includes `errdefer`, which runs only if the function exits with an error.

## Performance

Manual allocation is also known to be more appropriate for systems where memory is a scarce resource, due to faster reclamation. Memory systems can and do frequently "thrash" as the size of a program's working set approaches the size of available memory; unused objects in a garbage-collected system remain in an unreclaimed state for longer than in manually managed systems, because they are not immediately reclaimed, increasing the effective working set size.

Manual management has a number of documented performance disadvantages:

* Calls to `delete` and such incur an overhead each time they are made, this overhead can be amortized in garbage collection cycles. This is especially true of multithreaded applications, where delete calls must be synchronized.
* The allocation routine may be more complicated, and slower. Some garbage collection schemes, such as those with heap compaction, can maintain the free store as a simple array of memory (as opposed to the complicated implementations required by manual management schemes).

Manual memory management and garbage collection both suffer from potentially unbounded deallocation times – manual memory management because deallocating a single object may require deallocating its members, and recursively its members' members, etc., while garbage collection may have long collection cycles. This is especially an issue in real time systems, where unbounded collection cycles are generally unacceptable; real-time garbage collection is possible by pausing the garbage collector, while real-time manual memory management requires avoiding large deallocations, or manually pausing deallocation.

## See also

* Data segment
* Memory management § Manual memory management

## References

1. ↑ McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, Timothy P.; Levin, Michael I. (1985). LISP 1.5 Programmer's Manual (2nd ed.). p. Preface. http://www.softwarepreservation.org/projects/LISP/book/LISP 1.5 Programmers Manual.pdf.
2. ↑ "C++ creator calls for action to address 'serious attacks'" (in en). https://www.theregister.com/2025/03/02/c_creator_calls_for_action/.
3. ↑ The Rust Team (19 April 2026). "RAII - Rust by Example". The Rust Team. https://doc.rust-lang.org/rust-by-example/scope/raii.html.
4. ↑ JeanHeyd Meneide (2025). "Programming - C - defer, a mechanism for general purpose, lexical scope-based undo". WG 14. https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3734.pdf.

* Berger, E. D.; Zorn, B. G.; McKinley, K. S. (November 2002). "Reconsidering Custom Memory Allocation". OOPSLA '02. pp. 1–12. doi:10.1145/582419.582421. ISBN 1-58113-471-1. http://people.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf.

## External links

* The Memory Management Reference
* Richard Jones and Rafael Lins, Garbage Collection: Algorithms for Automated Dynamic Memory Management, Wiley and Sons (1996), ISBN 0-471-94148-4

* v
* t
* e

Memory management

* Memory management as a function of an operating system

Manual memory management|

* Static memory allocation
* C dynamic memory allocation
* new and delete (C++)

Virtual memory|

* Demand paging
* Page table
* Paging
* Virtual memory compression

Hardware|

* Memory management unit
* Translation lookaside buffer

Garbage collection|

* Boehm garbage collector
* Concurrent mark sweep collector
* Finalizer
* Garbage
* Garbage-first collector
* Mark-compact algorithm
* Reference counting
* Tracing garbage collection
* Strong reference
* Weak reference

Memory segmentation|

* Protected mode
* Real mode
* Virtual 8086 mode
* x86 memory segmentation

Memory safety|

* Buffer overflow
* Buffer over-read
* Dangling pointer
* Stack overflow

Issues|

* Fragmentation
* Memory leak
* Unreachable memory

Other|

* Automatic variable
* International Symposium on Memory Management
* Region-based memory management

0.00

(0 votes)

Original source: https://en.wikipedia.org/wiki/Manual memory management. Read more

|

Retrieved from "https://handwiki.org/wiki/index.php?title=Manual_memory_management&oldid=4409595"
*[v]: View this template
*[t]: Discuss this template
*[e]: Edit this template