UnsafeRawPointer假设MemoryBound与bindMemory [英] UnsafeRawPointer assumingMemoryBound vs. bindMemory

查看:280
本文介绍了UnsafeRawPointer假设MemoryBound与bindMemory的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能解释UnsafeRawPointer.assumimgMemoryBound(to:)UnsafeRawPointer.bindMemory(to:capacity:)之间的区别?

Can anyone explain what is difference between UnsafeRawPointer.assumimgMemoryBound(to:) and UnsafeRawPointer.bindMemory(to:capacity:)?

那么欢迎一个编译或运行时差的实际例子.

A practical example of compile or run time difference would be more then welcome.

Swift Doc 说到bindMemory(to:capacity:):

此API允许内存区域在程序的不同点上保存无关的类型.将未初始化的内存绑定到一种类型将为该内存准备存储该类型的值.已经初始化的绑定内存将内存中的值重新解释为新类型.如果旧值不是平凡的(需要销毁),或者曾经在覆盖之前从内存中读取它们,那么新类型必须与旧类型在布局上相互兼容.

This API allows a region of memory to hold unrelated types at different points in the program. Binding uninitialized memory to a type prepares the memory to store values of that type. Binding memory that is already initialized reinterprets the in-memory values as the new type. If the old values are either nontrivial (require destruction) or if they are ever read from memory before being overwritten, then the new type must be mutually layout compatible with the old type.

这是什么意思?将未初始化的内存绑定到一个类型会准备该内存来存储该类型的值?它分配了字节,对不对?那么bindMemory(to:capacity:)完成后有什么不同?

What does it mean Binding uninitialized memory to a type prepares the memory to store values of that type? It's allocated bytes, right? So what's different after bindMemory(to:capacity:) completes?

推荐答案

在Swift中分配的内存可以是:

Allocated memory in Swift can either be:

  • 未初始化的原始内存
  • 绑定到类型的未初始化内存
  • 绑定到类型的初始化内存

使用UnsafeMutableRawPointer.allocate(bytes:alignedTo:)分配内存时,会得到未初始化的原始内存.

When you allocate memory with UnsafeMutableRawPointer.allocate(bytes:alignedTo:), you get uninitialised raw memory.

使用UnsafeMutablePointer<T>.allocate(capacity:)分配内存时,会得到绑定到T类型的未初始化内存.

When you allocate memory with UnsafeMutablePointer<T>.allocate(capacity:), you get uninitialised memory that's bound to the type T.

  • bindMemory(to:capacity:) (重新)绑定了指针的内存为新类型,并为您提供带类型的指针以供访问.在上述任何一种状态下,都可以在指向内存的指针上调用它;尽管如果初始化了内存,则新的绑定类型必须与旧的绑定类型在布局上兼容,并且两种类型都应为请注意,此方法不会执行分配或初始化;它只是改变了内存的绑定类型.

    Note that this method doesn't perform allocation or initialisation; it merely changes the bound type of the memory.

    assumingMemoryBound(to:) 是一种获取您已经知道的原始指针中的类型化指针指向绑定到给定类型的内存.如果内存没有绑定到该类型,则通过您返回的类型化指针访问内存是未定义行为.

    这里要注意的重要一件事是,在给定的时间只能将内存绑定到一种类型.您可以自由地重新绑定到其他类型(具有上面对初始化内存的限制);但是,尝试访问绑定到给定类型为 unrelated 类型的内存会违反严格的别名,因此是未定义行为.

    One important thing to note here is that memory can only be bound to one type at a given time. You are free to rebind to other types (with the above restriction for initialised memory); however attempting to access memory bound to a given type as an unrelated type violates strict aliasing and is therefore undefined behaviour.

    要注意的另一件事是相关类型和布局兼容类型是独立的概念:

    Another thing to note is that related types and layout compatible types are independent concepts:

    • 如果绑定到U的内存可以按位重新解释为具有T类型,则T类型与布局兼容 .请注意,这不一定是双向关系.例如,如果(Int, Int)的一个实例"可以重新解释为2 x Int,则Int在布局上与(Int, Int)兼容.相反,事实并非如此.您不能从单个Int形成(Int, Int)值.

    • The type T is layout compatible with the type U if memory bound to type U can be bitwise reinterpreted as having type T. Note that this isn't necessarily a bidirectional relationship. For example, Int is layout compatible with (Int, Int) if one 'instance' of (Int, Int) can be reinterpreted as being 2 x Int. The reverse can't be true though; you can't form an (Int, Int) value from a single Int.

    如果可以使用重叠重叠式存储器作为别名,则这两种类型与相关.例如,如果您有UnsafePointer<T>UnsafePointer<U>,并且TU是不相关的类型,则它们不能指向彼此重叠的内存.

    Two types are related if you can alias overlapping memory with those types. For example, if you have an UnsafePointer<T> and an UnsafePointer<U>, if T and U are unrelated types, then they cannot point to memory that overlaps with each other.

    但是,我不认为Swift会为这些术语正式定义任何规则(我希望这会带来ABI稳定性).

    However, I don't believe Swift has officially defined any rules for these terms yet (I expect this'll come with ABI stability).

    那么bindMemory(to:capacity:)完成后有什么不同?

    So what's different after bindMemory(to:capacity:) completes?

    目前,什么都没有.如邮件中的 Andrew Trick所说列出 Martin链接到的讨论:

    Currently, nothing. As Andrew Trick says in the mailing list discussion that Martin linked to:

    绑定内存向编译器传达了该内存位置对于类型访问是安全的.在运行时什么都没有发生-直到有人编写类型安全消毒器为止.它会影响内存位置的抽象状态,而与用于访问该内存的指针变量无关.为了方便和清楚起见,绑定内存返回一个类型化的指针,但是该特定的指针值没有什么特别的.

    Binding memory communicates to the compiler that the memory locations are safe for typed access. Nothing happens at runtime--until someone writes a type safety sanitizer. It affects the abstract state of the memory location, independent of the pointer variable used to access that memory. Binding memory returns a typed pointer for convenience and clarity, but there’s nothing special about that particular pointer value.

    有关此主题的更多信息,请参见

    For further reading on this subject, see the memory model explanation section of SE-0107, as well as this unofficial guide to strict aliasing in Swift.

    这篇关于UnsafeRawPointer假设MemoryBound与bindMemory的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆