3 ms·
I tried to do this in a real program once. The program only ever runs for a fraction of a second and then exits, so it seemed like a good candidate. Unfortuna
by rwmj 2y ago
I tried to do this in a real program once. The program only ever runs for a fraction of a second and then exits, so it seemed like a good candidate. Unfortunately what happened after is that our company started running tools like Coverity which complained about leaked memory. The path of least resistance was to fix that by adding free()'s everywhere.
- matja 2y agoAnd then you accidently add a use-after-free bug by trying to satisfy a "correctness" tool...
- SubjectToChange 2y agoIt’s hard to fault the static analysis tooling here. Not freeing memory is, almost always, unintended behavior. Besides, if a business is going to blindly apply static analysis to their projects and then demand that every warning be “fixed”, then the tool really isn’t the problem. Still, any serious developer should, at the very least, have the patience to interrogate their code.
- nkrisc 2y agoThe tool doesn’t demand it be satisfied, a manager does.
- jmb99 2y agoCoverity will definitely warn you about use-after-free. It’s not a “correctness” tool, it’s a static analyzer and probably the best one out there (imo). Yes in this use case it’s probably not too important to care about, but really any code base of importance should be run through it on a fairly regular basis.
- adrianN 2y agoHow much use after free and double free did you have to fix?
- samatman 2y agoWorth pointing out that in Zig, you wouldn't have had this problem in the first place. The natural way to write a program of that nature is to create an arena allocator, immediately defer arena.deinit() on the next line, and then allocate to your heart's content. When the function returns, on an error or otherwise, the arena is freed. No need to go back later and add a bunch of free(), because you correctly implemented the memory policy as a matter of course, in two lines.
- frankjr 2y agoThat has nothing to do with a particular language, you could use individual allocations in Zig and end up with the same mess. Similarly, you could use memory arenas in C/... and not have the problem.
- samatman 2y agoDefaults matter. In C, allocation is customarily done with malloc, a single, global allocator. It's possible to bring in a memory arena, but in the case I was replying to, you'll note that they didn't. In Zig, everything which allocates receives an allocator to do so. So writing a top-to-bottom program of the sort indicated in the GP post, you're going to make an allocator first thing. That's when you decide to use an arena, and defer it, and you're done. You wouldn't decide to use malloc (which is available), or the GeneralPurposeAllocator, and then "end up with the same mess" by forgetting to release any of the memory, because the debug release mode, where all the work gets done, will loudly complain about that. It would take real stubbornness and conviction to write an all-malloc-no-free program in Zig, but using an arena is cheap and easy. So yes, it has everything to do with a particular language. If you wrote it in Rust, you'd end up with a borrow-checker-compatible program, if you wrote it in Nim, allocation would be taken care of by the runtime. In C, it's tempting to just use malloc and let the operating system do the GC when the process exits.