A typed pointer to some memory.
This is the only unsafe type in Crystal. If you are using a pointer, you are writing
unsafe code because a pointer doesn't know where it's pointing to nor how much memory
starting from it is valid. However, pointers make it possible to interface with C and
to implement efficient data structures. For example, both Array and Hash are
implemented using pointers.
You can obtain pointers in four ways: #new, #malloc, pointerof and by calling a C
function that returns a pointer.
pointerof(x), where x is a variable or an instance variable, returns a pointer to
that variable:
x = 1
ptr = pointerof(x)
ptr.value = 2
puts x #=> 2
Note that a pointer is falsey if it's null (if it's address is zero).
For a safe alternative, see Slice, which is a pointer with a length and with bounds checking.
Allocates size * sizeof(T) bytes from the system's heap initialized to the value returned by the block and returns a pointer to the first byte from that memory.
Allocates size * sizeof(T) bytes from the system's heap initialized to zero and returns a pointer to the first byte from that memory.
Allocates size * sizeof(T) bytes from the system's heap initialized to value and returns a pointer to the first byte from that memory.
Returns a pointer that points to the given memory address.
Returns a pointer whose memory address is zero.
Returns a new pointer whose address is this pointer's address incremented by other * sizeof(T).
Returns a new pointer whose address is this pointer's address decremented by other * sizeof(T).
Returns -1, 0 or 1 if this pointer's address is less, equal or greater than other's address, respectively.
Gets the value pointed at this pointer's address plus offset * sizeof(T).
Sets the value pointed at this pointer's address plus offset * sizeof(T).
Returns a PointerAppender for this pointer.
Clears (sets to "zero" bytes) a number of values pointed by this pointer.
Copies count elements from source into self.
Copies count elements from self into target.
Returns the address of this pointer.
Sets count consecutive values pointed by this pointer to the values returned by the block.
Compares count elements from this pointer and other, byte by byte.
Copies count elements from source into self.
Copies count elements from self into source.
Returns true if this pointer's address is zero.
Alias of #nil?
Tries to change the size of the allocation pointed to by this pointer to size, and returns that pointer.
Shuffles count consecutive values pointed by this pointer.
Swaps the contents pointed at the offsets i and j.
Appends a string representation of this pointer to the given IO, including its type and address in hexadecimal.
Returns a Slice that points to this pointer and is bounded by the given length.
Allocates size * sizeof(T) bytes from the system's heap initialized
to the value returned by the block and returns a pointer to the first byte from that memory.
The memory is allocated by the GC, so when there are
no pointers to this memory, it will be automatically freed.
# An Int32 occupies 4 bytes, so here we are requesting 16 bytes.
# i is an index in the range 0 .. 3
ptr = Pointer.malloc(4) { |i| i + 10 }
ptr[0] #=> 10
ptr[1] #=> 11
ptr[2] #=> 12
ptr[3] #=> 13Allocates size * sizeof(T) bytes from the system's heap initialized
to zero and returns a pointer to the first byte from that memory.
The memory is allocated by the GC, so when there are
no pointers to this memory, it will be automatically freed.
# Allocate memory for an Int32: 4 bytes
ptr = Pointer(Int32).malloc
ptr.value #=> 0
# Allocate memory for 10 Int32: 40 bytes
ptr = Pointer(Int32).malloc(10)
ptr[0] #=> 0
...
ptr[9] #=> 0
Allocates size * sizeof(T) bytes from the system's heap initialized
to value and returns a pointer to the first byte from that memory.
The memory is allocated by the GC, so when there are
no pointers to this memory, it will be automatically freed.
# An Int32 occupies 4 bytes, so here we are requesting 8 bytes
# initialized to the number 42
ptr = Pointer.malloc(2, 42)
ptr[0] #=> 42
ptr[1] #=> 42Returns a pointer that points to the given memory address. This doesn't allocate memory.
ptr = Pointer(Int32).new(5678)
ptr.address #=> 5678Returns a pointer whose memory address is zero. This doesn't allocate memory.
ptr = Pointer(Int32).null
ptr.address #=> 0Returns a new pointer whose address is this pointer's address incremented by other * sizeof(T).
ptr = Pointer(Int32).new(1234)
ptr.address #=> 1234
# An Int32 occupies four bytes
ptr2 = ptr + 1
ptr2.address #=> 1238Returns a new pointer whose address is this pointer's address decremented by other * sizeof(T).
ptr = Pointer(Int32).new(1234)
ptr.address #=> 1234
# An Int32 occupies four bytes
ptr2 = ptr - 1
ptr2.address #=> 1230Returns -1, 0 or 1 if this pointer's address is less, equal or greater than other's address, respectively.
See Object#<=>.
Gets the value pointed at this pointer's address plus offset * sizeof(T).
ptr = Pointer.malloc(4) { |i| i + 10 }
ptr[0] #=> 10
ptr[1] #=> 11
ptr[2] #=> 12
ptr[3] #=> 13Sets the value pointed at this pointer's address plus offset * sizeof(T).
ptr = Pointer(Int32).malloc(4) # [0, 0, 0, 0]
ptr[1] = 42
ptr2 = ptr + 1
ptr2.value #=> 42Returns a PointerAppender for this pointer.
Clears (sets to "zero" bytes) a number of values pointed by this pointer.
ptr = Pointer.malloc(6) { |i| i + 10 } # [10, 11, 12, 13, 14, 15]
ptr.clear(3)
ptr # [0, 0, 0, 13, 14, 15]Copies count elements from source into self.
If source and self overlap, behaviour is undefined.
Use #move_from if they overlap (slower but always works).
ptr1 = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr2 = Pointer.malloc(4) { |i| i + 11 } # [11, 12, 13, 14]
# ptr2 -> [11, 12, 13, 14]
# ^---^ <- copy this
# ptr1 -> [1, 2, 3, 4]
# ^---^ <- here
ptr1.copy_from(ptr2, 2)
ptr1[0] #=> 11
ptr1[1] #=> 12
ptr1[2] #=> 3
ptr1[3] #=> 4Copies count elements from self into target.
If self and target overlap, behaviour is undefined.
Use #move_to if they overlap (slower but always works).
ptr1 = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr2 = Pointer.malloc(4) { |i| i + 11 } # [11, 12, 13, 14]
# ptr1 -> [1, 2, 3, 4]
# ^---^ <- copy this
# ptr2 -> [11, 12, 13, 14]
# ^---^ <- here
ptr1.copy_to(ptr2, 2)
ptr2[0] #=> 1
ptr2[1] #=> 2
ptr2[2] #=> 13
ptr2[3] #=> 14Returns the address of this pointer.
ptr = Pointer(Int32).new(1234)
ptr.hash #=> 1234Sets count consecutive values pointed by this pointer to the values returned by the block.
ptr = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr.map!(4) { |value| value * 2 }
ptr # [2, 4, 6, 8]Compares count elements from this pointer and other, byte by byte.
Returns 0 if both pointers point to the same sequence of count bytes. Otherwise returns the difference between the first two differing bytes (treated as UInt8).
ptr1 = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr2 = Pointer.malloc(4) { |i| i + 11 } # [11, 12, 13, 14]
ptr1.memcmp(ptr2, 4) #=> -10
ptr2.memcmp(ptr1, 4) #=> 10
ptr1.memcmp(ptr1, 4) #=> 0Copies count elements from source into self. source and self may overlap; the copy is always done in a non-destructive manner.
ptr1 = Pointer.malloc(4) { |i| i + 1 } # ptr1 -> [1, 2, 3, 4]
ptr2 = ptr1 + 1 # ^--------- ptr2
# [1, 2, 3, 4]
# ^-----^ <- copy this
# ^------^ <- here
ptr2.move_from(ptr1, 3)
ptr1[0] #=> 1
ptr1[1] #=> 1
ptr1[2] #=> 2
ptr1[3] #=> 3Copies count elements from self into source. source and self may overlap; the copy is always done in a non-destructive manner.
ptr1 = Pointer.malloc(4) { |i| i + 1 } # ptr1 -> [1, 2, 3, 4]
ptr2 = ptr1 + 1 # ^--------- ptr2
# [1, 2, 3, 4]
# ^-----^ <- copy this
# ^------^ <- here
ptr1.move_to(ptr2, 3)
ptr1[0] #=> 1
ptr1[1] #=> 1
ptr1[2] #=> 2
ptr1[3] #=> 3Returns true if this pointer's address is zero.
a = 1
pointerof(a).nil? #=> false
b = Pointer(Int32).new(0)
b.nil? #=> trueAlias of #nil?
Tries to change the size of the allocation pointed to by this pointer to size, and returns that pointer.
Since the space after the end of the block may be in use, realloc may find it necessary to copy the block to a new address where more free space is available. The value of realloc is the new address of the block. If the block needs to be moved, realloc copies the old contents.
Remember to always assign the value of realloc.
ptr = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr = ptr.realloc(8)
ptr # [1, 2, 3, 4, 0, 0, 0, 0]Shuffles count consecutive values pointed by this pointer.
ptr = Pointer.malloc(4) { |i| i + 1 } # [1, 2, 3, 4]
ptr.shuffle!(4)
ptr # [3, 4, 1, 2]Swaps the contents pointed at the offsets i and j.
ptr = Pointer.malloc(4) { |i| i + 1 }
ptr[2] #=> 3
ptr[3] #=> 4
ptr.swap(2, 3)
ptr[2] #=> 4
ptr[3] #=> 3Appends a string representation of this pointer to the given IO,
including its type and address in hexadecimal.
ptr1 = Pointer(Int32).new(1234)
ptr1.to_s #=> Pointer(Int32)@0x4D2
ptr2 = Pointer(Int32).new(0)
ptr2.to_s #=> Pointer(Int32).nullReturns a Slice that points to this pointer and is bounded by the given length.
ptr = Pointer.malloc(6) { |i| i + 10 } # [10, 11, 12, 13, 14, 15]
slice = ptr.to_slice(4) #=> [10, 11, 12, 13]
slice.class #=> Slice(Int32)