Swift: How to use sizeof?

Use sizeof as follows:

let size = sizeof(Int)

sizeof uses the type as the parameter.

If you want the size of the anInt variable you can pass the dynamicType field to sizeof.

Like so:

var anInt: Int = 5
var anIntSize: Int = sizeof(anInt.dynamicType)

Or more simply (pointed out by user102008):

var anInt: Int = 5
var anIntSize: Int = sizeofValue(anInt)

In Xcode 8 with Swift 3 beta 6 there is no function sizeof (). But if you want, you can define one for your needs. This new sizeof function works as expected with an array. This was not possible with the old builtin sizeof function.

let bb: UInt8 = 1
let dd: Double = 1.23456

func sizeof <T> (_ : T.Type) -> Int
{
    return (MemoryLayout<T>.size)
}

func sizeof <T> (_ : T) -> Int
{
    return (MemoryLayout<T>.size)
}

func sizeof <T> (_ value : [T]) -> Int
{
    return (MemoryLayout<T>.size * value.count)
}

sizeof(UInt8.self)   // 1
sizeof(Bool.self)    // 1
sizeof(Double.self)  // 8
sizeof(dd)           // 8
sizeof(bb)           // 1

var testArray: [Int32] = [1,2,3,4]
var arrayLength = sizeof(testArray)  // 16

You need all versions of the sizeof function, to get the size of a variable and to get the correct size of a data-type and of an array.

If you only define the second function, then sizeof(UInt8.self) and sizeof(Bool.self) will result in "8". If you only define the first two functions, then sizeof(testArray) will result in "8".


Updated for Swift 3

Be careful that MemoryLayout<T>.size means something different than sizeof in C/Obj-C. You can read this old thread https://devforums.apple.com/message/1086617#1086617

Swift uses an generic type to make it explicit that the number is known at compile time.

To summarize, MemoryLayout<Type>.size is the space required for a single instance while MemoryLayout<Type>.stride is the distance between successive elements in a contiguous array. MemoryLayout<Type>.stride in Swift is the same as sizeof(type) in C/Obj-C.

To give a more concrete example:

struct Foo {
  let x: Int
  let y: Bool
}

MemoryLayout<Int>.size      // returns 8 on 64-bit
MemoryLayout<Bool>.size     // returns 1
MemoryLayout<Foo>.size      // returns 9
MemoryLayout<Foo>.stride    // returns 16 because of alignment requirements
MemoryLayout<Foo>.alignment // returns 8, addresses must be multiples of 8

Swift 3 now has MemoryLayout.size(ofValue:) which can look up the size dynamically.

Using a generic function that in turn uses MemoryLayout<Type> will have unexpected results if you e.g. pass it a reference of protocol type. This is because — as far as I know — the compiler then has all the type information it needs to fill in the values at compile time, which is not apparent when looking at the function call. You would then get the size of the protocol, not the current value.

Tags:

Swift