Search code examples
memoryvala

Difference between raw pointers and weak references in Vala?


(1) What's the difference between weak references, like

weak SomeType weak_ref = hard_ref;

or

unowned SomeType unowned_ref = hard_ref;

on the one hand and raw pointers like

SomeType* raw_ptr = hard_ref;

on the other, from a practical point of view?

At first, I though that weak references get reset automatically to null, as they do in Java, but they clearly don't. The docs only compare weak and hard references, but they don't mention raw pointers. Am I missing something?

(2) Furthermore:

  • Are there any concepts in Vala which allow resetting a weak reference or raw pointer automatically to null when the referenced object is finalized?
  • And are there any counterparts for classes like WeakHashMap or the Collections.newSetFromMap function from Java available in Vala?

Solution

  • There are few differences between weak references and raw pointers:

    • You can call delete on a raw pointer but not a weak reference.
    • Raw pointers can be stacked but references can't (i.e., you can have Foo**, but there's no equivalent of that for references.
    • If a type can be copied or reference counted, sensible things happen when you assign a weak reference to a strong reference. With raw pointers, memory management is entirely up to you.

    You can create a collection of weak pointers (e.g., ArrayList<unowned FileStream>). Java's WeakHashMap is based on there being a garbage collector and there is no garbage collector in Vala. References go out of scope and get cleaned up deterministically rather than as the result of memory pressure.

    It sounds like what you want is C++'s std::weak_ptr. Vala has WeakRef, which is similar. A WeakRef can hold a possibly disposed pointer and will return a strong reference to it or null on request. It only works for classes that derive from GLib.Object though. Unlike the C++ version, it sadly isn't statically type-safe (though it is run-time type-safe).