If you think a garbage collector and the lack of pointer arithmetic protect you from heap corruption bugs and developers deciding they're smart enough to manually manage memory for some extra speed, I've got some bad news for you. ;)
// p points to address 1000
p := (*int)(unsafe.Pointer(uintptr(1000)))
Of course, this is why use of the unsafe package is heavily discouraged.
The important distinction is that a 'Nullable' value type need not involve a pointer, which means it can entirely live on the stack, which dramatically limits the damage that can be done by corruption: Worst case, corruption sets the 'hasValue' flag to true, and you read an uninitialized struct off the stack. Much less catastrophic than a double-free or pointer into random memory (Though, of course, a determined attacker could probably make do with either).