Is there anyway to simulate the [NSString stringWithFormat:@"%p", myVar]
code in the new swift language ?
For example:
let str = "A String"
println(" str value \(str) has address: ?")
original title: "Printing a variable memory address in swift"
Is there anyway to simulate the [NSString stringWithFormat:@"%p", myVar]
code in the new swift language ?
For example:
let str = "A String"
println(" str value \(str) has address: ?")
Gibt es überhaupt eine Möglichkeit, den Code [NSString stringWithFormat: @ "% p", myVar] in der neuen schnellen Sprache zu simulieren? Zum Beispiel: let str = "A String" println ("str value \ (str) hat die Adresse :?")
Dies ist die Zusammenfassung nach der Übersetzung. Wenn Sie die vollständige Übersetzung anzeigen möchten, klicken Sie auf das Symbol "Übersetzen"
Swift 2
This is now part of the standard library:
unsafeAddressOf
.Swift 3
For Swift 3, use
withUnsafePointer
:Swift 4/5:
Prints the memory address of someVar. (thanks to @Ying)
Swift 3.1:
Prints the memory address of someVar.
Note that this answer was quite old. Many of the methods it describes no longer work. Specifically
.core
cannot be accessed anymore.However @drew's answer is correct and simple:
So the answer to your questions is:
Here is the original answer that was marked correct (for posterity/politeness):
Swift "hides" pointers, but they still exists under the hood. (because the runtime needs it, and for compatibility reasons with Objc and C)
There are few things to know however, but first how to print the memory address of a Swift String?
This prints the memory address of the string, if you open XCode -> Debug Workflow -> View Memory and go to the printed address, you will see the raw data of the string. Since this is a string literal, this is a memory address inside the storage of the binary (not stack or heap).
However, if you do
This will be on the stack, because the string is created at runtime
NOTE: .core._baseAddress is not documented, I found it looking in the variable inspector, and it may be hidden in the future
_baseAddress is not available on all types, here another example with a CInt
Where
takesInt
is a C helper function like thisOn the Swift side, this function is
takesInt(intptr: CMutablePointer<CInt>)
, so it takes a CMutablePointer to a CInt, and you can obtain it with &varnameThe function prints
0x7fff5fbfed98
, an at this memory address you will find 289 (in hexadecimal notation). You can change its content with*intptr = 123456
Now, some other things to know.
String, in swift, is a primitive type, not an object.
CInt is a Swift type mapped to the C int Type.
If you want the memory address of an object, you have to do something different.
Swift has some Pointer Types that can be used when interacting with C, and you can read about them here: Swift Pointer Types
Moreover, you can understand more about them exploring their declaration (cmd+click on the type), to understand how to convert a type of pointer into another
printptr
is a C helper function I created, with this implementationAgain, an example of the address printed:
0x6000000530b0
, and if you go through memory inspector you will find your NSStringOne thing you can do with pointers in Swift (this can even be done with inout parameters)
Or, interacting with Objc / c
To get the (heap) address of an object
(Edit: Swift 1.2 now includes a similar function called
unsafeAddressOf
.)In Objective-C this would be
[NSString stringWithFormat:@"%p", o]
.o
is a reference to the instance. So ifo
is assigned to another variableo2
, the returned address foro2
will be the same.This doesn't apply to structs (including
String
) and primitive types (likeInt
), because those live directly on the stack. But we can retrieve the location on the stack.To get the (stack) address of a struct, build-in type or object reference
In Objective-C this would be
[NSString stringWithFormat:@"%p", &o]
or[NSString stringWithFormat:@"%p", &i]
.s
is struct. So ifs
is assigned to another variables2
, the value will be copied and the returned address fors2
will be different.How it fits together (pointer recap)
Like in Objective-C, there are two different addresses associated with
o
. The first is the location of the object, the second is the location of the reference (or pointer) to the object.Yes, this means that the content of address 0x7fff5fbfe658 is the number 0x6100000011d0 as the debugger can tell us:
So, except for strings being structs, internally this all pretty much works the same as in (Objective-)C.
(Current as of Xcode 6.3)
TL;DR
(Gist)
In Swift we deal either with value types (structures) or reference types (classes). When doing:
Some memory is allocated at address X, and at this address we will find the value 42. Doing
&n
creates a pointer pointing to address X, therefore&n
tells us wheren
is located.When doing:
Memory is allocated in two places:
As said, classes are reference types: so the value of
c
is located at address X, at which we'll find the value of Y. And at address Y + 16 we'll findfoo
and at address Y + 24 we'll findbar
(at + 0 and + 8 we'll find type data and reference counts, I can't tell you much more about this...).0x2a
is 42 (foo) and0x54
is 84 (bar).In both cases, using
&n
or&c
will give us address X. For value types, that's what we want, but isn't for reference types.When doing:
We create a pointer on the reference, i.e. a pointer that points to address X. Same thing when using
withUnsafePointer(&c) {}
.Now that we have a better understanding of what goes on under the hood, and that we now that at address X we'll find address Y (which is the one we want) we can do the following to get it:
Verifying:
There are other ways to do this:
toOpaque()
actually callsunsafeBitCast(c, to: UnsafeMutableRawPointer.self)
.I hope this helped... it did for me ?.
Reference Types:
===
identity operator is used to check 2 objects point to the same reference.ObjectIdentifier
to get the memory addressCode:
Value Types:
If you just want to see this in the debugger and not do anything else with it, there's no need to actually get the
Int
pointer. To get the string representation of an object's address in memory, just use something like this:Example usage:
Additionally, remember that you can simply print an object without overriding its
description
, and it will show its pointer address alongside more descriptive (if oft cryptic) text.Swift 4
Usage:
In Swift4 about Array:
Just use this:
The other answers are fine, though I was looking for a way to get the pointer address as an integer:
Just a little follow-up.
The answer @Drew provide can only be used for class type.
The answer @nschum provide can only be for struct type.
However if you use the second method to get address of a array with value type element. Swift will copy the whole array because in Swift array is copy-on-write and Swift can't make sure it behave this way once it pass control over to C/C++ (Which is trigger by using
&
to get address). And if you use first method instead , it will automatically convertArray
toNSArray
which is surely something we don't want.So the most simple and unified way I found is using lldb instruction
frame variable -L yourVariableName
.Or you can combine their answers:
This is for Swift 3.
Like @CharlieMonroe I wanted to get the address as an integer. Specifically, I wanted the address of a Thread object for use as a thread ID in a diagnostic logging module, for situations where no thread name was available.
Based on Charlie Monroe's code, here's what I've come up with so far. But beware, I'm very new to Swift, this may not be correct ...
The last statement is there because without it I was getting addresses like 0x60000007DB3F. The modulo operation in the last statement converts that into 0x7DB3F.
My solution on Swift 3
this code create description like default description
<MyClass: 0x610000223340>
This is certainly not the fastest or safest way to go about it. But it works for me. This will allow for any nsobject subclass to adopt this property.