“This is the 21st day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Pointer security
- When you create an object, you need to create a
The heap
Allocate memory space. But the lifetime of the object is finite, that is, the lifetime of the memory space is finite, which means that if we use a pointer to the memory space, if the lifetime of the current memory space ends (the reference count is0
), the current pointer will be calledWild pointer
; - The created memory space is bounded if we create a size of
N
When we access the array through a pointer toN+1
Will be generated when we access an unknown memory spaceCrossing the line
; - Pointer types may differ from memory value types;
The pointer is not safe
Pointer types
Pointers in Swift fall into two categories:
typed pointer
Specify a data type pointer;raw pointer
A pointer to an unspecified data type (also known asThe original pointer
);
The pointer types we used during development are basically as follows:
Swift | Object-C | note | |
---|---|---|---|
unsafePointer | const T * | Pointers and what they point to are immutable | Specify type data pointer;T Used to specify the data type |
unsafeMutablePointer | T * | Pointers and what they point to are mutable | |
unsafeRawPointer | const void * | The memory region to which the pointer points is undetermined | Immutable content |
unsafeMutableRawPointer | void * | The memory region to which the pointer points is undetermined | Content of the variable |
unsafeBufferPointer | Continuous immutable memory space | Specify the type | |
unsafeMutableBufferPointer | Continuous variable memory space | Specify the type | |
unsafeRawBufferPointer | Native continuous immutable memory space | Type not specified | |
unsafeMutableRawBufferPointer | Native continuous variable memory space |
Use of native Pointers
UnsafeMutableRawPointer we use RawPointer to store 4 UnsafeMutableRawPointer.
We notice that in the above code there is this code:
p.advanced(by: i * MemoryLayout<Int>.stride).storeBytes(of: i, as: Int.self)
Copy the code
As: int. self tells the system what type of data we’re storing
If advanced is missing, the result will be wrong. This is because we need to store data in memory according to the size of the data type offset. Therefore, when storing data, we need to base the address on P. Each time we store data, we need to offset the step * index of the current data type.
So what is MemoryLayout for?
MemoryLayout
Let’s use the following example to illustrate the use of MemoryLayout:
size
: Actual size of the current type in memory:8 plus 16 plus 1 is 25
stride
: The step size in memory for the current type, which needs to be aligned with memory:8 + 16 + 8(1 complement is 8) = 32
- Like when we need to store two in memory in a row
Teacher
Type struct when from the firstTeacher
To the secondTeacher
The size that the middle pointer needs to move isStep length
;
- Like when we need to store two in memory in a row
alignment
: Memory alignment size;
Use of generic Pointers
Generic Pointers are also known as type Pointers. Compared to native Pointers, generic Pointers already specify the type of the pointer.
**0x0000000100008080** is the memory pointer to the age variable we get;
For age, what if we want to modify it?
pointee
The data type of the data to which the pointer is executed;
Note that ptr.pointee cannot be modified in the trailing closure of withUnsafePointer, as shown below:
The pointee returned in withUnsafePointer is immutable;
If we want to modifyptr.pointee
, need to usewithUnsafeMutablePointer
:
withUnsafePointer
Returns an immutable pointer whose contents are immutable;withUnsafeMutablePointer
Returns a mutable pointer whose content is mutable;
Pointer manipulation
Now that we know about Pointers, we can use Pointers to manipulate memory. Let’s look at the following code:
In the code above, we create a memory space that can hold up to six structures of type Person; Since we already know the type of pointer, we create the memory space with UnsafeMutablePointer;
ptr
Equivalent to the first address of the memory space we created, throughptr
We can manipulate this memory region;deinitialize
anddeallocate
In pairs, used to reclaim memory;deinitialize
It can be understood that the current memory space is all set to0
;