Why Julia doesn't throw error if pre-declared array is reassigned to a new differently sized array?

Yes the reference x is being reassigned. New heap memory was created in the line x=rand(100), you can check it yourself via pointer. E.g.

julia> x::Vector{Float64} = zeros(100);
julia> @show pointer(x)
pointer(x) = Ptr{Float64} @0x00007ffbd0f47840
Ptr{Float64} @0x00007ffbd0f47840
julia> x = rand(100);
julia> @show pointer(x)
pointer(x) = Ptr{Float64} @0x00007ffbd0a3e6c0
Ptr{Float64} @0x00007ffbd0a3e6c0

The theory is that the garbage collector (GC) will deallocate the heap memory used to store the contents of zero(100) IF no other variable in scope is using it. For example:

julia> x = randn(3)

3-element Vector{Float64}:
  0.02116688818771611
 -2.496066399533173
  1.6321445374322279

julia> @show pointer(x)
pointer(x) = Ptr{Float64} @0x00007f555e4a3ec0
Ptr{Float64} @0x00007f555e4a3ec0

julia> y = x
3-element Vector{Float64}:
  0.02116688818771611
 -2.496066399533173
  1.6321445374322279

julia> x = nothing

julia> @show pointer(y)
pointer(y) = Ptr{Float64} @0x00007f555e4a3ec0
Ptr{Float64} @0x00007f555e4a3ec0

julia> @show pointer(x) # throws error
ERROR: MethodError: no method matching pointer(::Nothing)

The GC will not deallocate y next time it runs because y is still pointing to the location 0x00007f555e4a3ec0.

Stack-allocated variables like SVector from StaticArrays.jl won’t need the GC to free up. If you really want a C-like experience without using Array types for some special cases, then there is always the C library in Julia to allocate and free memory, e.g. Libc.free() and Libc.malloc(). An example usage case for coding like C back in 2022 (whichever Julia version that was) is to do static compilation, e.g. see Successful Static Compilation of Julia Code for use in Production.

3 Likes