“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 aThe heapAllocate 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 ofNWhen we access the array through a pointer toN+1Will 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 pointerSpecify a data type pointer;
  • raw pointerA 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;TUsed 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 rowTeacherType struct when from the firstTeacherTo the secondTeacherThe size that the middle pointer needs to move isStep length;
  • 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?

  • pointeeThe 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:

  • withUnsafePointerReturns an immutable pointer whose contents are immutable;
  • withUnsafeMutablePointerReturns 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;

  • ptrEquivalent to the first address of the memory space we created, throughptrWe can manipulate this memory region;
  • deinitializeanddeallocateIn pairs, used to reclaim memory;
    • deinitializeIt can be understood that the current memory space is all set to0;