UnsafeMutableRawPointer

struct UnsafeMutableRawPointer

A raw pointer for accessing and manipulating untyped data.

Inheritance Strideable
Associated Types
public typealias Pointee = UInt8

The UnsafeMutableRawPointer type provides no automated memory management, no type safety, and no alignment guarantees. You are responsible for handling the life cycle of any memory you work with through unsafe pointers, to avoid leaks or undefined behavior.

Memory that you manually manage can be either untyped or bound to a specific type. You use the UnsafeMutableRawPointer type to access and manage raw bytes in memory, whether or not that memory has been bound to a specific type.

Understanding a Pointer's Memory State

The memory referenced by an UnsafeMutableRawPointer instance can be in one of several states. Many pointer operations must only be applied to pointers with memory in a specific state---you must keep track of the state of the memory you are working with and understand the changes to that state that different operations perform. Memory can be untyped and uninitialized, bound to a type and uninitialized, or bound to a type and initialized to a value. Finally, memory that was allocated previously may have been deallocated, leaving existing pointers referencing unallocated memory.

Raw, Uninitialized Memory

Raw memory that has just been allocated is in an uninitialized, untyped state. Uninitialized memory must be initialized with values of a type before it can be used with any typed operations.

You can use methods like initializeMemory(as:from:) and moveInitializeMemory(as:from:count:) to bind raw memory to a type and initialize it with a value or series of values. To bind uninitialized memory to a type without initializing it, use the bindMemory(to:count:) method. These methods all return typed pointers for further typed access to the memory.

Typed Memory

Memory that has been bound to a type, whether it is initialized or uninitialized, is typically accessed using typed pointers---instances of UnsafePointer and UnsafeMutablePointer. Initialization, assignment, and deinitialization can be performed using UnsafeMutablePointer methods.

Memory that has been bound to a type can be rebound to a different type only after it has been deinitialized or if the bound type is a trivial type. Deinitializing typed memory does not unbind that memory's type. The deinitialized memory can be reinitialized with values of the same type, bound to a new type, or deallocated.

Note: A trivial type can be copied bit for bit with no indirection or reference-counting operations. Generally, native Swift types that do not contain strong or weak references or other forms of indirection are trivial, as are imported C structs and enumerations.

When reading from or writing to memory as raw bytes when that memory is bound to a type, you must ensure that you satisfy any alignment requirements. Writing to typed memory as raw bytes must only be performed when the bound type is a trivial type.

Raw Pointer Arithmetic

Pointer arithmetic with raw pointers is performed at the byte level. When you add to or subtract from a raw pointer, the result is a new raw pointer offset by that number of bytes. The following example allocates four bytes of memory and stores 0xFF in all four bytes:

let bytesPointer = UnsafeMutableRawPointer.allocate(byteCount: 4, alignment: 1)
bytesPointer.storeBytes(of: 0xFFFF_FFFF, as: UInt32.self)

// Load a value from the memory referenced by 'bytesPointer'
let x = bytesPointer.load(as: UInt8.self)       // 255

// Load a value from the last two allocated bytes
let offsetPointer = bytesPointer + 2
let y = offsetPointer.load(as: UInt16.self)     // 65535

The code above stores the value 0xFFFF_FFFF into the four newly allocated bytes, and then loads the first byte as a UInt8 instance and the third and fourth bytes as a UInt16 instance.

Always remember to deallocate any memory that you allocate yourself.

bytesPointer.deallocate()

Implicit Casting and Bridging

When calling a function or method with an UnsafeMutableRawPointer parameter, you can pass an instance of that specific pointer type, pass an instance of a compatible pointer type, or use Swift's implicit bridging to pass a compatible pointer.

For example, the print(address:as:) function in the following code sample takes an UnsafeMutableRawPointer instance as its first parameter:

func print<T>(address p: UnsafeMutableRawPointer, as type: T.Type) {
    let value = p.load(as: type)
    print(value)
}

As is typical in Swift, you can call the print(address:as:) function with an UnsafeMutableRawPointer instance. This example passes rawPointer as the initial parameter.

// 'rawPointer' points to memory initialized with `Int` values.
let rawPointer: UnsafeMutableRawPointer = ...
print(address: rawPointer, as: Int.self)
// Prints "42"

Because typed pointers can be implicitly cast to raw pointers when passed as a parameter, you can also call print(address:as:) with any mutable typed pointer instance.

let intPointer: UnsafeMutablePointer<Int> = ...
print(address: intPointer, as: Int.self)
// Prints "42"

Alternatively, you can use Swift's implicit bridging to pass a pointer to an instance or to the elements of an array. Use inout syntax to implicitly create a pointer to an instance of any type. The following example uses implicit bridging to pass a pointer to value when calling print(address:as:):

var value: Int = 23
print(address: &value, as: Int.self)
// Prints "23"

A mutable pointer to the elements of an array is implicitly created when you pass the array using inout syntax. This example uses implicit bridging to pass a pointer to the elements of numbers when calling print(address:as:).

var numbers = [5, 10, 15, 20]
print(address: &numbers, as: Int.self)
// Prints "5"

Important:

var number = 5
let numberPointer = UnsafeMutableRawPointer(&number)
// Accessing 'numberPointer' is undefined behavior.

Initializers

init init(_:) Required

Creates a new raw pointer from the given typed pointer.

Use this initializer to explicitly convert other to an UnsafeMutableRawPointer instance. This initializer creates a new pointer to the same address as other and performs no allocation or copying.

  • Parameter other: The typed pointer to convert.

Declaration

public init<T>(_ other: UnsafeMutablePointer<T>)
init init(_:) Required

Creates a new raw pointer from an AutoreleasingUnsafeMutablePointer instance.

  • Parameter other: The pointer to convert.

Declaration

public init<T>(_ other: AutoreleasingUnsafeMutablePointer<T>)
init init(mutating:) Required

Creates a new mutable raw pointer from the given immutable raw pointer.

Use this initializer to explicitly convert other to an UnsafeMutableRawPointer instance. This initializer creates a new pointer to the same address as other and performs no allocation or copying.

  • Parameter other: The immutable raw pointer to convert.

Declaration

public init(mutating other: UnsafeRawPointer)
init init?(_:) Required

Creates a new raw pointer from the given typed pointer.

Use this initializer to explicitly convert other to an UnsafeMutableRawPointer instance. This initializer creates a new pointer to the same address as other and performs no allocation or copying.

  • Parameter other: The typed pointer to convert. If other is nil, the result is nil.

Declaration

public init?<T>(_ other: UnsafeMutablePointer<T>?)
init init?(_:) Required

Creates a new raw pointer from an AutoreleasingUnsafeMutablePointer instance.

  • Parameter other: The pointer to convert. If other is nil, the result is nil.

Declaration

public init?<T>(_ other: AutoreleasingUnsafeMutablePointer<T>?)
init init?(mutating:) Required

Creates a new mutable raw pointer from the given immutable raw pointer.

Use this initializer to explicitly convert other to an UnsafeMutableRawPointer instance. This initializer creates a new pointer to the same address as other and performs no allocation or copying.

  • Parameter other: The immutable raw pointer to convert. If other is nil, the result is nil.

Declaration

public init?(mutating other: UnsafeRawPointer?)

Instance Variables

var customPlaygroundQuickLook Required

A custom playground Quick Look for this instance.

If this type has value semantics, the PlaygroundQuickLook instance should be unaffected by subsequent mutations.

Declaration

var customPlaygroundQuickLook: _PlaygroundQuickLook

Instance Methods

func advanced(by n: Int) -> UnsafeMutableRawPointer Required

Returns a value that is offset the specified distance from this value.

Use the advanced(by:) method in generic code to offset a value by a specified distance. If you're working directly with numeric values, use the addition operator (+) instead of this method.

func addOne<T: Strideable>(to x: T) -> T
    where T.Stride: ExpressibleByIntegerLiteral
{
    return x.advanced(by: 1)
}

let x = addOne(to: 5)
// x == 6
let y = addOne(to: 3.5)
// y = 4.5

If this type's Stride type conforms to BinaryInteger, then for a value x, a distance n, and a value y = x.advanced(by: n), x.distance(to: y) == n. Using this method with types that have a noninteger Stride may result in an approximation.

  • Parameter n: The distance to advance this value.

Complexity: O(1)

Declaration

public func advanced(by n: Int) -> UnsafeMutableRawPointer
func assumingMemoryBound(to: T.Type) -> UnsafeMutablePointer<T> Required

Returns a typed pointer to the memory referenced by this pointer, assuming that the memory is already bound to the specified type.

Use this method when you have a raw pointer to memory that has already been bound to the specified type. The memory starting at this pointer must be bound to the type T. Accessing memory through the returned pointer is undefined if the memory has not been bound to T. To bind memory to T, use bindMemory(to:capacity:) instead of this method.

  • Parameter to: The type T that the memory has already been bound to.

Declaration

public func assumingMemoryBound<T>(to: T.Type) -> UnsafeMutablePointer<T>
func bindMemory(to type: T.Type, capacity count: Int) -> UnsafeMutablePointer<T> Required

Binds the memory to the specified type and returns a typed pointer to the bound memory.

Use the bindMemory(to:capacity:) method to bind the memory referenced by this pointer to the type T. The memory must be uninitialized or initialized to a type that is layout compatible with T. If the memory is uninitialized, it is still uninitialized after being bound to T.

In this example, 100 bytes of raw memory are allocated for the pointer bytesPointer, and then the first four bytes are bound to the Int8 type.

let count = 4
let bytesPointer = UnsafeMutableRawPointer.allocate(
        bytes: 100,
        alignedTo: MemoryLayout<Int8>.alignment)
let int8Pointer = bytesPointer.bindMemory(to: Int8.self, capacity: count)

After calling bindMemory(to:capacity:), the first four bytes of the memory referenced by bytesPointer are bound to the Int8 type, though they remain uninitialized. The remainder of the allocated region is unbound raw memory. All 100 bytes of memory must eventually be deallocated.

Warning: A memory location may only be bound to one type at a time. The behavior of accessing memory as a type unrelated to its bound type is undefined.

Declaration

public func bindMemory<T>(to type: T.Type, capacity count: Int) -> UnsafeMutablePointer<T>
func copyMemory(from source: UnsafeRawPointer, byteCount: Int) Required

Copies the specified number of bytes from the given raw pointer's memory into this pointer's memory.

If the byteCount bytes of memory referenced by this pointer are bound to a type T, then T must be a trivial type, this pointer and source must be properly aligned for accessing T, and byteCount must be a multiple of MemoryLayout<T>.stride.

The memory in the region source..<(source + byteCount) may overlap with the memory referenced by this pointer.

After calling copyMemory(from:byteCount:), the byteCount bytes of memory referenced by this pointer are initialized to raw bytes. If the memory is bound to type T, then it contains values of type T.

Declaration

@inlinable public func copyMemory(from source: UnsafeRawPointer, byteCount: Int)
func deallocate() Required

Deallocates the previously allocated memory block referenced by this pointer.

The memory to be deallocated must be uninitialized or initialized to a trivial type.

Declaration

@inlinable public func deallocate()
func initializeMemory(as type: T.Type, from source: UnsafePointer<T>, count: Int) -> UnsafeMutablePointer<T> Required

Initializes the memory referenced by this pointer with the values starting at the given pointer, binds the memory to the values' type, and returns a typed pointer to the initialized memory.

The memory referenced by this pointer must be uninitialized or initialized to a trivial type, and must be properly aligned for accessing T.

The following example allocates enough raw memory to hold four instances of Int8, and then uses the initializeMemory(as:from:count:) method to initialize the allocated memory.

let count = 4
let bytesPointer = UnsafeMutableRawPointer.allocate(
        bytes: count * MemoryLayout<Int8>.stride,
        alignedTo: MemoryLayout<Int8>.alignment)
let values: [Int8] = [1, 2, 3, 4]
let int8Pointer = values.withUnsafeBufferPointer { buffer in
    return bytesPointer.initializeMemory(as: Int8.self,
              from: buffer.baseAddress!,
              count: buffer.count)
}
// int8Pointer.pointee == 1
// (int8Pointer + 3).pointee == 4

// After using 'int8Pointer':
int8Pointer.deallocate(count)

After calling this method on a raw pointer p, the region starting at p and continuing up to p + count * MemoryLayout<T>.stride is bound to type T and initialized. If T is a nontrivial type, you must eventually deinitialize or move from the values in this region to avoid leaks. The instances in the region source..<(source + count) are unaffected.

Declaration

@inlinable public func initializeMemory<T>(as type: T.Type, from source: UnsafePointer<T>, count: Int) -> UnsafeMutablePointer<T>
func initializeMemory(as type: T.Type, repeating repeatedValue: T, count: Int) -> UnsafeMutablePointer<T> Required

Initializes the memory referenced by this pointer with the given value, binds the memory to the value's type, and returns a typed pointer to the initialized memory.

The memory referenced by this pointer must be uninitialized or initialized to a trivial type, and must be properly aligned for accessing T.

The following example allocates enough raw memory to hold four instances of Int8, and then uses the initializeMemory(as:repeating:count:) method to initialize the allocated memory.

let count = 4
let bytesPointer = UnsafeMutableRawPointer.allocate(
        byteCount: count * MemoryLayout<Int8>.stride,
        alignment: MemoryLayout<Int8>.alignment)
let int8Pointer = myBytes.initializeMemory(
        as: Int8.self, repeating: 0, count: count)

// After using 'int8Pointer':
int8Pointer.deallocate()

After calling this method on a raw pointer p, the region starting at self and continuing up to p + count * MemoryLayout<T>.stride is bound to type T and initialized. If T is a nontrivial type, you must eventually deinitialize or move from the values in this region to avoid leaks.

Declaration

@inlinable public func initializeMemory<T>(as type: T.Type, repeating repeatedValue: T, count: Int) -> UnsafeMutablePointer<T>
func load(fromByteOffset offset: Int = 0, as type: T.Type) -> T Required

Returns a new instance of the given type, constructed from the raw memory at the specified offset.

The memory at this pointer plus offset must be properly aligned for accessing T and initialized to T or another type that is layout compatible with T.

Declaration

@inlinable public func load<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T
func moveInitializeMemory(as type: T.Type, from source: UnsafeMutablePointer<T>, count: Int) -> UnsafeMutablePointer<T> Required

Initializes the memory referenced by this pointer with the values starting at the given pointer, binds the memory to the values' type, deinitializes the source memory, and returns a typed pointer to the newly initialized memory.

The memory referenced by this pointer must be uninitialized or initialized to a trivial type, and must be properly aligned for accessing T.

The memory in the region source..<(source + count) may overlap with the destination region. The moveInitializeMemory(as:from:count:) method automatically performs a forward or backward copy of all instances from the source region to their destination.

After calling this method on a raw pointer p, the region starting at p and continuing up to p + count * MemoryLayout<T>.stride is bound to type T and initialized. If T is a nontrivial type, you must eventually deinitialize or move from the values in this region to avoid leaks. Any memory in the region source..<(source + count) that does not overlap with the destination region is returned to an uninitialized state.

Declaration

@inlinable public func moveInitializeMemory<T>(as type: T.Type, from source: UnsafeMutablePointer<T>, count: Int) -> UnsafeMutablePointer<T>
func storeBytes(of value: T, toByteOffset offset: Int = 0, as type: T.Type) Required

Stores the given value's bytes into raw memory at the specified offset.

The type T to be stored must be a trivial type. The memory at this pointer plus offset must be properly aligned for accessing T. The memory must also be uninitialized, initialized to T, or initialized to another trivial type that is layout compatible with T.

After calling storeBytes(of:toByteOffset:as:), the memory is initialized to the raw bytes of value. If the memory is bound to a type U that is layout compatible with T, then it contains a value of type U. Calling storeBytes(of:toByteOffset:as:) does not change the bound type of the memory.

Note: A trivial type can be copied with just a bit-for-bit copy without any indirection or reference-counting operations. Generally, native Swift types that do not contain strong or weak references or other forms of indirection are trivial, as are imported C structs and enums.

If you need to store a copy of a nontrivial value into memory, or to store a value into memory that contains a nontrivial value, you cannot use the storeBytes(of:toByteOffset:as:) method. Instead, you must know the type of value previously in memory and initialize or assign the memory. For example, to replace a value stored in a raw pointer p, where U is the current type and T is the new type, use a typed pointer to access and deinitialize the current value before initializing the memory with a new value.

let typedPointer = p.bindMemory(to: U.self, capacity: 1)
typedPointer.deinitialize(count: 1)
p.initializeMemory(as: T.self, to: newValue)

Declaration

@inlinable public func storeBytes<T>(of value: T, toByteOffset offset: Int = 0, as type: T.Type)

Type Methods

func <(x: Self, y: Self) -> Bool Required

Returns a Boolean value indicating whether the value of the first argument is less than that of the second argument.

This function is the only requirement of the Comparable protocol. The remainder of the relational operator functions are implemented by the standard library for any type that conforms to Comparable.

Declaration

@inlinable public static func <(x: Self, y: Self) -> Bool
func ==(x: Self, y: Self) -> Bool Required

Returns a Boolean value indicating whether two values are equal.

Equality is the inverse of inequality. For any values a and b, a == b implies that a != b is false.

Declaration

@inlinable public static func ==(x: Self, y: Self) -> Bool
func allocate(byteCount: Int, alignment: Int) -> UnsafeMutableRawPointer Required

Allocates uninitialized memory with the specified size and alignment.

You are in charge of managing the allocated memory. Be sure to deallocate any memory that you manually allocate.

The allocated memory is not bound to any specific type and must be bound before performing any typed operations. If you are using the memory for a specific type, allocate memory using the UnsafeMutablePointer.allocate(capacity:) static method instead.

Declaration

@inlinable public static func allocate(byteCount: Int, alignment: Int) -> UnsafeMutableRawPointer