Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Heuristic:Duckdb Duckdb Memory Management Rules

From Leeroopedia




Knowledge Sources
Domains Code_Quality, C_Plus_Plus
Last Updated 2026-02-07 12:00 GMT

Overview

DuckDB prohibits raw `malloc`/`new`/`delete`; use smart pointers exclusively, strongly preferring `unique_ptr` over `shared_ptr`, and `idx_t` over `size_t`.

Description

DuckDB enforces strict memory management rules to prevent leaks and dangling pointers. Raw memory allocation (`malloc`, `new`, `delete`) is considered a code smell and should never be used in core code. The project strongly prefers `unique_ptr` for ownership semantics, using `shared_ptr` only when absolutely necessary (e.g., shared catalog objects). Additionally, the project uses the `idx_t` type alias instead of `size_t` for all offset/index/count values, and the `D_ASSERT` macro instead of standard `assert`.

Usage

Apply these rules when writing any C++ code for the DuckDB core (`src/` directory). These conventions are enforced during code review and violations will block PR merging.

The Insight (Rule of Thumb)

  • Rule 1: Never use `malloc`, `new`, or `delete`. Use smart pointers instead.
    • Use `make_uniq<T>(...)` (DuckDB's wrapper) or `std::make_unique<T>(...)`.
  • Rule 2: Strongly prefer `unique_ptr` over `shared_ptr`. Only use `shared_ptr` when ownership is truly shared.
  • Rule 3: Use `idx_t` instead of `size_t` for all offsets, indices, and counts.
  • Rule 4: Use `[u]int(8|16|32|64)_t` instead of `int`, `long`, `uint` etc.
  • Rule 5: Use `const` references for non-trivial arguments (e.g., `std::vector`, `std::string`).
  • Rule 6: Use `D_ASSERT` instead of `assert`. Asserts should never be triggered by user input.
  • Rule 7: Use exceptions only for query-terminating errors. Use return values for expected/recoverable errors.
  • Trade-off: Slightly more verbose code in exchange for memory safety and clear ownership semantics.

Reasoning

Smart pointers provide automatic memory management with clear ownership semantics. `unique_ptr` makes ownership transfer explicit (via `std::move`) and has zero runtime overhead compared to raw pointers. `shared_ptr` has atomic reference counting overhead and makes ownership ambiguous, which is why it's discouraged.

The `idx_t` convention avoids sign-comparison warnings and makes the intent of a variable clearer (it's a count/index, not an arbitrary size).

Code evidence from `CONTRIBUTING.md:80-81`:

* Do not use `malloc`, prefer the use of smart pointers. Keywords `new` and
  `delete` are a code smell.
* Strongly prefer the use of `unique_ptr` over `shared_ptr`, only use
  `shared_ptr` if you **absolutely** have to.

Type conventions from `CONTRIBUTING.md:86`:

* Use `[u]int(8|16|32|64)_t` instead of `int`, `long`, `uint` etc. Use `idx_t`
  instead of `size_t` for offsets/indices/counts of any kind.

Error handling from `CONTRIBUTING.md:115-118`:

* Use exceptions **only** when an error is encountered that terminates a query.
* Use `D_ASSERT` to assert. Use **assert** only when failing the assert means
  a programmer error. Assert should never be triggered by user input.

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment