---
title: "Visualizing Rust's Vtables: How dyn Trait Works In Memory"
slug: visualizing-rusts-vtables-how-dyn-trait-works-in-memory
url: https://listedarticles.com/articles/visualizing-rusts-vtables-how-dyn-trait-works-in-memory
canonical_url: https://sofiabelen.github.io/projects/visualizing-rusts-vtables-how-dyn-trait-works-in-memory/
content_type: blog_post
language: en
published_at: 2026-09-04T00:00:00.000Z
updated_at: 2026-09-16T16:12:03.618Z
author: "Sofia Belen"
author_url: https://sofiabelen.github.io
authored_by: agent
publisher: "sofiabelen.github.io"
publisher_url: https://sofiabelen.github.io
topics: ["Rust", "Memory Layout", "Systems Programming", "C++", "Programming"]
license: all-rights-reserved
word_count: 299
reading_minutes: 1
citation: "Sofia Belen, sofiabelen.github.io. \"Visualizing Rust's Vtables: How dyn Trait Works In Memory.\" 4 Sept 2026. https://sofiabelen.github.io/projects/visualizing-rusts-vtables-how-dyn-trait-works-in-memory/ (all-rights-reserved)"
# The full text follows. The web page shows an extract and sends readers
# to the source above; quote the citation and link the canonical URL.
---

# Visualizing Rust's Vtables: How dyn Trait Works In Memory

> A Rust learner coming from C++ examines how dynamic dispatch works in memory, contrasting Rust's wide pointer approach, a data pointer paired with a vtable pointer, with C++'s in-object vtable pointer. The post also explores zero-sized types, object safety rules, and the specific situations where dynamic dispatch is necessary.

> **Indexed summary.** This entry is an agent-written synopsis of an article first published at [sofiabelen.github.io](https://sofiabelen.github.io/projects/visualizing-rusts-vtables-how-dyn-trait-works-in-memory/). Read the original for the full text.

The author's explicit goal is to understand Rust not by drawing 1:1 parallels with C++ but by probing the why of its design choices. Starting with two C++ approaches to polymorphism, virtual functions and CRTP, the post builds toward Rust's `dyn Trait` by examining what static dispatch can and cannot express.

## Key points

- Static dispatch (generics and monomorphization) generates a separate compiled function per concrete type; zero runtime cost but types must be known at compile time.
- Rust's zero-sized types, structs with no fields, have a `size_of` of 0, unlike C++ where every object must have at least 1 byte for unique address guarantees. Rust tracks identity through ownership rather than memory addresses.
- `&dyn Draw` is a wide pointer: 16 bytes on 64-bit systems, comprising a data pointer and a vtable pointer. The vtable holds the specific `draw()` implementation to call at runtime.
- The dispatch choice is made at the call site, not the type definition, which differs from C++ where marking a method `virtual` commits the class to dynamic dispatch.
- `Vec<Box<dyn Draw>>` is the idiomatic way to hold a heterogeneous collection in Rust; `Box<dyn Trait>` has uniform size because it is always a wide pointer.
- Object safety rules, no methods returning `Self`, no generic method parameters, exist because the compiler cannot know the concrete type at runtime to allocate the correct return size.

## Why it matters

Understanding wide pointers and vtable layout is practical knowledge for writing idiomatic Rust code and for debugging unexpected size or dispatch behaviour. The comparison with C++ illuminates specific design choices Rust made rather than inherited.

---

*Source: [Visualizing Rust's Vtables: How dyn Trait Works In Memory](https://sofiabelen.github.io/projects/visualizing-rusts-vtables-how-dyn-trait-works-in-memory/)*
