Skip to content

Instantly share code, notes, and snippets.

@sunilsharma08
Forked from nyg/MemoryAddress.swift
Created September 12, 2020 02:47
Show Gist options
  • Select an option

  • Save sunilsharma08/3e19bd24e16f9713ab8d6c1778a1eed7 to your computer and use it in GitHub Desktop.

Select an option

Save sunilsharma08/3e19bd24e16f9713ab8d6c1778a1eed7 to your computer and use it in GitHub Desktop.

Revisions

  1. @nyg nyg revised this gist Sep 26, 2017. 1 changed file with 7 additions and 0 deletions.
    7 changes: 7 additions & 0 deletions MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -39,3 +39,10 @@ var structInstance = MyStruct()
    let structInstanceAddress = MemoryAddress(of: &structInstance)
    print(String(format: "%018p", structInstanceAddress.intValue))
    print(structInstanceAddress)

    /* output
    0x0000000101916c80
    0x0000000101916c80
    0x00000001005e3000
    0x00000001005e3000
    */
  2. @nyg nyg revised this gist Sep 26, 2017. 2 changed files with 41 additions and 37 deletions.
    41 changes: 41 additions & 0 deletions MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    // https://stackoverflow.com/a/45777692/5536516

    import Foundation

    struct MemoryAddress<T>: CustomStringConvertible {

    let intValue: Int

    var description: String {
    let length = 2 + 2 * MemoryLayout<UnsafeRawPointer>.size
    return String(format: "%0\(length)p", intValue)
    }

    // for structures
    init(of structPointer: UnsafePointer<T>) {
    intValue = Int(bitPattern: structPointer)
    }
    }

    extension MemoryAddress where T: AnyObject {

    // for classes
    init(of classInstance: T) {
    intValue = unsafeBitCast(classInstance, to: Int.self)
    // or Int(bitPattern: Unmanaged<T>.passUnretained(classInstance).toOpaque())
    }
    }

    /* Testing */

    class MyClass { let foo = 42 }
    var classInstance = MyClass()
    let classInstanceAddress = MemoryAddress(of: classInstance) // and not &classInstance
    print(String(format: "%018p", classInstanceAddress.intValue))
    print(classInstanceAddress)

    struct MyStruct { let foo = 1 } // using empty struct gives weird results (see StackOverflow comments)
    var structInstance = MyStruct()
    let structInstanceAddress = MemoryAddress(of: &structInstance)
    print(String(format: "%018p", structInstanceAddress.intValue))
    print(structInstanceAddress)
    37 changes: 0 additions & 37 deletions MemoryLocation.swift
    Original file line number Diff line number Diff line change
    @@ -1,37 +0,0 @@
    import Foundation

    struct MemoryLocation<T> {

    let stringValue: String
    let intValue: Int

    // for structures
    init(of structPointer: UnsafePointer<T>) {
    stringValue = structPointer.debugDescription
    intValue = Int(bitPattern: structPointer)
    }
    }

    extension MemoryLocation where T: AnyObject {

    // for classes
    init(of classInstance: T) {
    let rawPointer = Unmanaged<T>.passUnretained(classInstance).toOpaque()
    stringValue = rawPointer.debugDescription
    intValue = Int(bitPattern: rawPointer)
    }
    }

    /* Playground */

    class A { let foo = 1 }
    var a = A()
    let mla = MemoryLocation(of: a)
    mla.stringValue
    String(format: "%018p", mla.intValue)

    struct B { let foo = 1 } // using empty struct gives weird results (see StackOverflow comments)
    var b = B()
    let mlb = MemoryLocation(of: &b)
    mlb.stringValue
    String(format: "%018p", mlb.intValue)
  3. @nyg nyg revised this gist Sep 23, 2017. 1 changed file with 7 additions and 23 deletions.
    30 changes: 7 additions & 23 deletions MemoryLocation.swift
    Original file line number Diff line number Diff line change
    @@ -1,26 +1,14 @@
    // https://stackoverflow.com/a/45777692/5536516

    import Foundation

    struct MemoryLocation<T> {

    let pointer: UnsafePointer<T>
    let stringValue: String
    let intValue: Int

    // for structures
    init(of structPointer: UnsafePointer<T>) {
    pointer = structPointer
    }

    var pointee: T {
    return pointer.pointee
    }

    var stringValue: String {
    return pointer.debugDescription
    }

    var intValue: Int {
    return Int(bitPattern: pointer)
    stringValue = structPointer.debugDescription
    intValue = Int(bitPattern: structPointer)
    }
    }

    @@ -29,8 +17,8 @@ extension MemoryLocation where T: AnyObject {
    // for classes
    init(of classInstance: T) {
    let rawPointer = Unmanaged<T>.passUnretained(classInstance).toOpaque()
    let opaquePointer = OpaquePointer(rawPointer)
    pointer = UnsafePointer<T>(opaquePointer)
    stringValue = rawPointer.debugDescription
    intValue = Int(bitPattern: rawPointer)
    }
    }

    @@ -39,15 +27,11 @@ extension MemoryLocation where T: AnyObject {
    class A { let foo = 1 }
    var a = A()
    let mla = MemoryLocation(of: a)
    mla.pointee.foo
    mla.pointer
    mla.stringValue
    String(format: "%018p", mla.intValue)

    struct B { let foo = 1 } // using empty struct gives weird results (see StackOverflow comments)
    var b = B()
    let mlb = MemoryLocation(of: &b)
    mlb.pointee.foo
    mlb.pointer
    mlb.stringValue
    String(format: "%018p", mlb.intValue)
    String(format: "%018p", mlb.intValue)
  4. @nyg nyg revised this gist Sep 17, 2017. 2 changed files with 53 additions and 97 deletions.
    97 changes: 0 additions & 97 deletions MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -1,97 +0,0 @@
    // https://stackoverflow.com/a/45777692/5536516

    import Foundation

    /* For objects */

    class MyClass { var foo = 1 }
    var myClass = MyClass()

    let opaquePointer = Unmanaged<MyClass>.passUnretained(myClass).toOpaque()
    print(opaquePointer)

    let intPointer = unsafeBitCast(myClass, to: Int.self)
    print(String(format: "%p", intPointer))

    /* For structures */

    struct MyStruct { var foo = 1 }
    var myStruct = MyStruct()

    let unsafeMutablePointer = UnsafeMutablePointer<MyStruct>(&myStruct)
    print(unsafeMutablePointer)

    let pointerWithUnmanaged = Unmanaged<AnyObject>.fromOpaque(&myStruct).toOpaque()
    print(pointerWithUnmanaged)

    let pointerFromClosure = { (p: UnsafePointer) in p }(&myStruct)
    print(pointerFromClosure)

    withUnsafePointer(to: &myStruct) { print($0) }

    func getStructAddress(p: UnsafeRawPointer) {

    // Warning: 'unsafeBitCast' from 'UnsafeRawPointer' to 'Int'
    // can be replaced with 'bitPattern:' initializer on 'Int'
    let pointerFromBitCast = unsafeBitCast(p, to: Int.self)
    print(String(format: "%p", pointerFromBitCast))

    let pointerFromInt = Int(bitPattern: p)
    print(String(format: "%p", pointerFromInt))
    }

    getStructAddress(p: &myStruct)

    /* output
    0x0000000100f063d0
    0x100f063d0
    0x000000010040f498
    0x000000010040f498
    0x000000010040f498
    0x000000010040f498
    0x10040f498
    0x10040f498
    */
    /* verifying
    (lldb) frame variable -L myClass
    scalar(0x0000000100f063d0): (GetAnyAddress.MyClass) myClass = 0x0000000100f063d0 {
    0x0000000100f063e0: foo = 1
    }
    (lldb) frame variable -L myStruct
    0x000000010040f498: (GetAnyAddress.MyStruct) myStruct = {
    0x000000010040f498: foo = 1
    }
    */

    struct MemoryLocation {

    let pointer: UnsafeMutableRawPointer

    init<T: AnyObject>(of classInstance: T) {
    pointer = Unmanaged<T>.passUnretained(classInstance).toOpaque()
    }

    init(of structPointer: UnsafeMutableRawPointer) {
    pointer = structPointer
    }

    var stringValue: String {
    return pointer.debugDescription
    }

    var intValue: Int {
    return Int(bitPattern: pointer)
    }
    }

    class A { let foo = 1 }
    var a = A()
    let mla = MemoryLocation(of: a) // & should not be used for class instances
    mla.stringValue
    String(format: "%018p", mla.intValue)

    struct B { let foo = 1 }
    var b = B()
    let mlb = MemoryLocation(of: &b) // using & is necessary, otherwise the structure will be copied
    mlb.stringValue
    String(format: "%018p", mlb.intValue)
    53 changes: 53 additions & 0 deletions MemoryLocation.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    // https://stackoverflow.com/a/45777692/5536516

    import Foundation

    struct MemoryLocation<T> {

    let pointer: UnsafePointer<T>

    // for structures
    init(of structPointer: UnsafePointer<T>) {
    pointer = structPointer
    }

    var pointee: T {
    return pointer.pointee
    }

    var stringValue: String {
    return pointer.debugDescription
    }

    var intValue: Int {
    return Int(bitPattern: pointer)
    }
    }

    extension MemoryLocation where T: AnyObject {

    // for classes
    init(of classInstance: T) {
    let rawPointer = Unmanaged<T>.passUnretained(classInstance).toOpaque()
    let opaquePointer = OpaquePointer(rawPointer)
    pointer = UnsafePointer<T>(opaquePointer)
    }
    }

    /* Playground */

    class A { let foo = 1 }
    var a = A()
    let mla = MemoryLocation(of: a)
    mla.pointee.foo
    mla.pointer
    mla.stringValue
    String(format: "%018p", mla.intValue)

    struct B { let foo = 1 } // using empty struct gives weird results (see StackOverflow comments)
    var b = B()
    let mlb = MemoryLocation(of: &b)
    mlb.pointee.foo
    mlb.pointer
    mlb.stringValue
    String(format: "%018p", mlb.intValue)
  5. @nyg nyg revised this gist Aug 21, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,7 @@ getStructAddress(p: &myStruct)
    0x000000010040f498
    0x10040f498
    0x10040f498
    /*
    */
    /* verifying
    (lldb) frame variable -L myClass
    scalar(0x0000000100f063d0): (GetAnyAddress.MyClass) myClass = 0x0000000100f063d0 {
  6. @nyg nyg revised this gist Aug 21, 2017. 1 changed file with 34 additions and 1 deletion.
    35 changes: 34 additions & 1 deletion MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -61,4 +61,37 @@ scalar(0x0000000100f063d0): (GetAnyAddress.MyClass) myClass = 0x0000000100f063d0
    0x000000010040f498: (GetAnyAddress.MyStruct) myStruct = {
    0x000000010040f498: foo = 1
    }
    */
    */

    struct MemoryLocation {

    let pointer: UnsafeMutableRawPointer

    init<T: AnyObject>(of classInstance: T) {
    pointer = Unmanaged<T>.passUnretained(classInstance).toOpaque()
    }

    init(of structPointer: UnsafeMutableRawPointer) {
    pointer = structPointer
    }

    var stringValue: String {
    return pointer.debugDescription
    }

    var intValue: Int {
    return Int(bitPattern: pointer)
    }
    }

    class A { let foo = 1 }
    var a = A()
    let mla = MemoryLocation(of: a) // & should not be used for class instances
    mla.stringValue
    String(format: "%018p", mla.intValue)

    struct B { let foo = 1 }
    var b = B()
    let mlb = MemoryLocation(of: &b) // using & is necessary, otherwise the structure will be copied
    mlb.stringValue
    String(format: "%018p", mlb.intValue)
  7. @nyg nyg revised this gist Aug 20, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ import Foundation
    class MyClass { var foo = 1 }
    var myClass = MyClass()

    let opaquePointer = Unmanaged<AnyObject>.passUnretained(myClass).toOpaque()
    let opaquePointer = Unmanaged<MyClass>.passUnretained(myClass).toOpaque()
    print(opaquePointer)

    let intPointer = unsafeBitCast(myClass, to: Int.self)
  8. @nyg nyg created this gist Aug 20, 2017.
    64 changes: 64 additions & 0 deletions MemoryAddress.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    // https://stackoverflow.com/a/45777692/5536516

    import Foundation

    /* For objects */

    class MyClass { var foo = 1 }
    var myClass = MyClass()

    let opaquePointer = Unmanaged<AnyObject>.passUnretained(myClass).toOpaque()
    print(opaquePointer)

    let intPointer = unsafeBitCast(myClass, to: Int.self)
    print(String(format: "%p", intPointer))

    /* For structures */

    struct MyStruct { var foo = 1 }
    var myStruct = MyStruct()

    let unsafeMutablePointer = UnsafeMutablePointer<MyStruct>(&myStruct)
    print(unsafeMutablePointer)

    let pointerWithUnmanaged = Unmanaged<AnyObject>.fromOpaque(&myStruct).toOpaque()
    print(pointerWithUnmanaged)

    let pointerFromClosure = { (p: UnsafePointer) in p }(&myStruct)
    print(pointerFromClosure)

    withUnsafePointer(to: &myStruct) { print($0) }

    func getStructAddress(p: UnsafeRawPointer) {

    // Warning: 'unsafeBitCast' from 'UnsafeRawPointer' to 'Int'
    // can be replaced with 'bitPattern:' initializer on 'Int'
    let pointerFromBitCast = unsafeBitCast(p, to: Int.self)
    print(String(format: "%p", pointerFromBitCast))

    let pointerFromInt = Int(bitPattern: p)
    print(String(format: "%p", pointerFromInt))
    }

    getStructAddress(p: &myStruct)

    /* output
    0x0000000100f063d0
    0x100f063d0
    0x000000010040f498
    0x000000010040f498
    0x000000010040f498
    0x000000010040f498
    0x10040f498
    0x10040f498
    /*
    /* verifying
    (lldb) frame variable -L myClass
    scalar(0x0000000100f063d0): (GetAnyAddress.MyClass) myClass = 0x0000000100f063d0 {
    0x0000000100f063e0: foo = 1
    }
    (lldb) frame variable -L myStruct
    0x000000010040f498: (GetAnyAddress.MyStruct) myStruct = {
    0x000000010040f498: foo = 1
    }
    */