The billion dollar mistake is making NULL a valid pointer value, not use after free--which has nothing to do with null pointers and which I didn't comment on, as the comment I responded to only mentioned Zig in regard to the billion dollar mistake. The billion dollar mistake doesn't occur in Zig because null is not a valid value for a pointer, only an optional pointer, which must be unwrapped with an explicit null test.
The approach taken is the same as in virtually every other language that has avoided the billion dollar mistake -- null is not a valid pointer value, and instead there's an additional union type (called Optional, Maybe, etc.) that can hold Some(pointer) or None. Zig, like some other languages, extends this union beyond pointers to other types.