Is sizeof() giving incorrect results instead of errors for structs with mutable fields?

Example:

struct IMMUT
    a::Int64
    b::Bool
end

sizeof(IMMUT(0, false)) == 16 # true since this is "with padding", as the documentation describes.

struct MUT
    a::Array
end

vctr = Int64[1, 2, 3]

sizeof(vctr) == 24 # true
sizeof(MUT(vctr)) == 24 # false
sizeof(MUT(vctr)) == 8 # true

In this case, I believe sizeof is returning the size of a pointer to the array, which on a 64 bit system is 8 bytes.

Since the array is heap allocated and tracked by the GC, it cannot be stored inline in the struct. The struct therefore contains a reference that points to the healp allocated object. It is for this same reason that isbits will return false on the second struct.

In this case, I believe sizeof is returning the size of a pointer to the array, which on a 64 bit system is 8 bytes.

This makes sense.

Is this the expected/correct behavior for sizeof() though?

I’m using Julia 1.9.0, and this is the documentaiton:

sizeof(T::DataType)
  sizeof(obj)

  Size, in bytes, of the canonical binary representation of the given DataType T, if any. Or the size, in bytes, of object obj if it is not a DataType.

  See also Base.summarysize.

  Examples
  ≑≑≑≑≑≑≑≑≑≑

  julia> sizeof(Float32)
  4
  
  julia> sizeof(ComplexF64)
  16
  
  julia> sizeof(1.0)
  8
  
  julia> sizeof(collect(1.0:10.0))
  80
  
  julia> struct StructWithPadding
             x::Int64
             flag::Bool
         end
  
  julia> sizeof(StructWithPadding) # not the sum of `sizeof` of fields due to padding
  16
  
  julia> sizeof(Int64) + sizeof(Bool) # different from above
  9

  If DataType T does not have a specific size, an error is thrown.

  julia> sizeof(AbstractArray)
  ERROR: Abstract type AbstractArray does not have a definite size.
  Stacktrace:
  [...]

  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  sizeof(str::AbstractString)

  Size, in bytes, of the string str. Equal to the number of code units in str multiplied by the size, in bytes, of one code unit in str.

  Examples
  ≑≑≑≑≑≑≑≑≑≑

  julia> sizeof("")
  0
  
  julia> sizeof("βˆ€")
  3

Yes. Maybe Base.summarysize is closer to what you want, though I don’t think that is implemented to count all relevant memory either.

julia> Base.summarysize(Int64[])
40

julia> Base.summarysize(vctr) # +24 for 3 elements
64

julia> Base.summarysize(MUT(vctr)) # +8 for 1 pointer
72
4 Likes