Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't understand the distinction between spatial and temporal memory safety - from what I gather, spatial memory safety is just preventing out of bounds access of arrays, dereferencing uninitialized or otherwise invalid pointers. But use after free absolutely results in the same kinds of errors (accessing unused memory, or memory used by someone else).

I also don't understand how one can sidestep the issue of ownership of memory - let's say you have a situation where a given piece of memory has changing or ambiguous ownership - like an event sent between two components, that has allocated some dynamic memory.

I'm not saying this just because, I've encountered this exact issue before - many C libraries have event systems where the ownership is not obvious coming from the code - like the sender owns the event, and if you store a reference to it, then you have a dangling pointer if the sender decides to clean it up.

That's why it's important to make it either obvious who owns what, or have some automatic system like GC or unique_ptr or the borrow checker.

This is a very real issue and the only way you can fix it is to follow strong informal conventions the language has no way of enforcing or even communicating to the user.

You mention Zig has a temporal memory management solution of a different kind - may I ask you what it is, because I haven't really seen it.



> But use after free absolutely results in the same kinds of errors (accessing unused memory, or memory used by someone else).

That two bugs result in the same or similar outcome doesn't mean they're as common or as equally exploitable, which is why, in practice, it is distinctly a more dangerous weakness in the lists maintained by MITRE.

> I also don't understand how one can sidestep the issue of ownership of memory

It's not about side-stepping. There are many kinds of bugs in software, and while we'd like to avoid all of them, some problems are, in practice, more problematic. After all, Rust similarly "sidesteps" - as in doesn't prevent - all non-memory-safety-related weaknesses, some of which are more dangerous than dynamic memory safety. If Zig isn't good enough because it doesn't prevent temporal memory safety violations, then by the exact same logic, Rust isn't good enough because it doesn't prevent, say, injection vulnerabilities, that are more dangerous than temporal memory safety vulnerabilities.

> I'm not saying this just because, I've encountered this exact issue before

Sure, it's a real and serious issue. But injection is a more serious issue, which Rust doesn't prevent, and spatial memory violations are also a more serious issue, which Zig prevents just as Rust does.

> That's why it's important to make it either obvious who owns what, or have some automatic system like GC or unique_ptr or the borrow checker.

It is, but it's even more important to prevent code injection attacks, yet Rust doesn't do that. It all comes down to how much it's worth it to pay to prevent certain bugs.

Rust was built because its designers believed that memory safety wasn't worth paying the higher memory footprint or the lower predictability of more popular memory-safe languages, or else there would have been no need for Rust in the first place. Similarly, it's just as reasonable to believe that the price you pay for temporal memory safety in Rust is not worth it.

> You mention Zig has a temporal memory management solution of a different kind - may I ask you what it is, because I haven't really seen it.

It's not a safe solution by any means (as the language doesn't enforce temporal memory safety, just as C++ doesn't), but memory allocation and deallocation in Zig is not the same as in C or C++. In particular, Zig functions that allocate are explicitly marked by having an Allocator parameter (https://zig.guide/standard-library/allocators/). Unlike in C, in Zig you know which functions allocate and using which allocator. That's how Zig is such a great fit for arenas.

Because Zig is built around custom allocators, you can also choose allocators that offer use-after-free, double-free, and memory-leak protection, and do so selectively (unlike in C): https://sinclairtarget.com/blog/2025/09/getting-my-allocator...


I feel like one thing that wasn't made clear - it's not necessarily the job of the programming language to prevent certain issues - SQL injection for example is something that should be handled by the framework (by not allowing to write SQL directly, but using commands with parameters). All the other higher priority issues are like that, it's not within the scope of a language to prevent such issues, just as Rust or Zig or whatever will never prevent phishing attacks.

As for temporal vs spatial memory safety issues, I agree that Zig does maybe help in that a bit (if component A sends an event to B, then A,B and the events having a separate allocator would work) - though I'm not sure if it doesn't introduce its own footguns (how do I know which allocator needs to free which object).

I don't know I haven't used Zig at all, so no idea how all this works out in practice. Memory issues are 100% solved by languages like Java with GC and I wouldn't say they have made software that much less buggy.


> it's not within the scope of a language to prevent such issues

As someone working on adding such a feature to Java, I beg to differ. Python has also recently added a language feature to address injection attacks (https://peps.python.org/pep-0750/).

> Memory issues are 100% solved by languages like Java with GC and I wouldn't say they have made software that much less buggy.

Well, again, the question isn't how many bugs you have, but what the impact of these bugs is. Violations of spatial memory safety are both common and relatively easy to exploit into very dangerous attacks, which is why it's important that Rust and Zig prevent them. But everything is a question of cost and benefit, as in, how much extra effort, or RAM, or CPU it's worth it to avoid certain bugs. The answer depends on the nature of the bug, the nature of the project, and the preferences of developers. Zig and Rust compromise on both correctness and effort, but their compromises are somewhat different. We just don't know if one of these approaches is more likely to be a better sweet spot in more situations (where these languages are used), and if so which.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: