The Mojo ManualXYZ Homework Edition

⇩ Download ▾

6.1 Intro to pointers

A pointer is an indirect reference to one or more values stored in memory. The pointer is a value that holds an address to memory, and provides APIs to store and retrieve values to that memory. The value pointed to by a pointer is also known as a pointee.

The Mojo standard library includes several types of pointers, which provide different sets of features. All of these pointer types are parameterized—they can point to any type of value, and the value type is specified as a parameter. For example, the following code creates an OwnedPointer that points to an Int value:

from std.memory import OwnedPointer

var ptr: OwnedPointer[Int]
ptr = OwnedPointer(100)

The ptr variable has a value of type OwnedPointer[Int]. The pointer points to a value of type Int, as shown in Figure 1.

A local variable, ptr, points to an OwnedPointer[Int] which points to an Int pointee. The value of the OwnedPointer is the address of the Int pointee.

Accessing the memory—to retrieve or update a value—is called dereferencing the pointer. You can dereference a pointer by following the variable name with an empty pair of square brackets:

# Update an initialized value
ptr[] += 10
# Access an initialized value
print(ptr[])

Pointer terminology

Before jumping into the pointer types, here are a few terms you'll run across. Some of them may already be familiar to you.

Pointer types

The Mojo standard library includes several pointer types with different characteristics:

Table 1 summarizes the different types of pointers:

PointerOwnedPointerArcPointer
SafeConditionally 1YesYes
Memory allocationManual via alloc()Implicit 2Implicit 2
Owns pointee(s)No 3YesYes
Implicitly copyableYesNoYes
NullableNoNoNo
Can point to uninitialized memoryYesNoNo
Can point to multiple values (array-like access)YesNoNo

1 Pointer has both safe and unsafe methods. Unsafe methods are named with the unsafe_ prefix (or require an unsafe_ keyword argument).

2 OwnedPointer and ArcPointer implicitly allocate memory when you initialize the pointer with a value.

3 Pointer provides unsafe methods for initializing and destroying instances of the stored type. The user is responsible for managing the lifecycle of stored values.

The following sections provide more details on each pointer type.

Pointer

The Pointer type is Mojo's primary pointer type. It can access a block of contiguous memory locations, which might be uninitialized. Heap-allocated memory is accessed through a Pointer; the other pointer types wrap a Pointer to access heap memory.

The Pointer type is safe when used to point to an existing value:

var ptr = Pointer(to=some_value)
print(ptr[])

When used this way, the Pointer type carries the origin of the value it points to. It can be used to store a reference in a struct field.

The Pointer type also provides a number of unsafe methods you can use to access dynamically-allocated memory, initialize and destroy stored values, and more. These features are useful for low-level systems programming tasks, but you need to use them with care. Some examples of unsafe pointer uses include:

For more information, see Using pointers.

OwnedPointer

The OwnedPointer type is a smart pointer designed for cases where there is single ownership of the underlying data. An OwnedPointer points to a single item, which is passed in when you initialize the OwnedPointer. The OwnedPointer allocates memory and moves or copies the value into the reserved memory.

from std.memory import OwnedPointer

var o_ptr = OwnedPointer(some_big_struct^)

An owned pointer can hold almost any type of item, but when constructing an OwnedPointer, the stored item must be either Movable or Copyable.

Since an OwnedPointer is designed to enforce single ownership, the pointer itself can be moved, but not copied.

OwnedPointer does provide an initializer that creates a new OwnedPointer by copying the stored value from an existing OwnedPointer. This results in two owned pointers, each with its own separate allocation and its own copy of the stored value.

ArcPointer

An ArcPointer is a reference-counted smart pointer, ideal for shared resources where the last owner for a given value may not be clear. Like an OwnedPointer, it points to a single value, and it allocates memory when you initialize the ArcPointer with a value:

from std.memory import ArcPointer

var attributesDict: Dict[String, String] = {}
var attributes = ArcPointer(attributesDict^)

Unlike an OwnedPointer, an ArcPointer can be freely copied. All instances of a given ArcPointer share a reference count, which is incremented whenever the ArcPointer is copied and decremented whenever an instance is destroyed. When the reference count reaches zero, the stored value is destroyed and the allocated memory is freed.

You can use ArcPointer to implement safe reference-semantic types. For example, in the following code snippet SharedDict uses an ArcPointer to store a dictionary. Copying an instance of SharedDict only copies the ArcPointer, not the dictionary, which is shared between all of the copies.

from std.memory import ArcPointer


struct SharedDict(ImplicitlyCopyable):
    var attributes: ArcPointer[Dict[String, String]]

    def __init__(out self):
        var attributesDict: Dict[String, String] = {}
        self.attributes = ArcPointer(attributesDict^)

    def __init__(out self, *, copy: Self):
        self.attributes = copy.attributes

    def __setitem__(mut self, key: String, value: String):
        self.attributes[][key] = value

    def __getitem__(self, key: String) -> String:
        return self.attributes[].get(key, default="")


def main():
    var thing1 = SharedDict()
    var thing2 = thing1
    thing1["Flip"] = "Flop"
    print(thing2["Flip"])
Show output ✓ Verified · Mojo 1.1.0 (8189361e)
Flop

Adapted from the Mojo Manual and the MAX GPU programming guides, part of the Modular Platform repository (github.com/modular/modular), Copyright (c) Modular Inc., licensed under the Apache License v2.0 with LLVM Exceptions. Changes were made: reformatted as an accessible XYZ web edition with build-verified example outputs. Mojo and MAX are trademarks of Modular Inc.; this edition is not affiliated with or endorsed by Modular. License: Apache-2.0 WITH LLVM-exception.

These eBooks are a prerelease and are not yet certified conformant with WCAG 2.1 AA or any other accessibility standard. Every page is built against an automated accessibility gate, and our target for the published editions is WCAG 2.2 Level AA. If something is unusable, please tell us.