3 ms·
Memory management in C is really not that hard. If it's big, use malloc or calloc. If it's small and of fixed size, use the stack. Don't use globals unless y
by reality_czech 13y ago
Memory management in C is really not that hard. If it's big, use malloc or calloc. If it's small and of fixed size, use the stack. Don't use globals unless you really, really have a good reason.
Yes, you can get leaks with malloc. But valgrind is actually really good at finding them. So if you have reasonable unit tests, you can just run valgrind on all of them and get a lot of coverage.
The problems that Nethack is having are basically self-inflicted. They opted to use setjmp and longjmp to emulate exceptions. So they don't have a good way of cleaning up things they malloc'ed. setjmp and longjmp are basically a way of implementing a cross-function "goto". it's just as bad as it sounds. Not to mention, they use a lot of functions like sprintf that have basically been banned by everyone else in the world. Hopefully they're not using gets()...
You don't need to implement crazygonuts memory management unless you're writing a high-performance database or kernel or something. Certainly not for a text adventure! Just. Use. Malloc. So this whole thing is just an exercise in making something really simple into something really complicated. Which I guess is what Nethack is, anyway.
- logicchains 13y agoAs someone who likes C and Go for their lack of support for exceptions, the thought that someone might actually want to implement exceptions in C is mind-blowing.
- deletes 13y agoAllocating chunks over ~1024B repeatedly becomes really slow, because malloc tries to return as much memory back to the system when you free. This takes magnitudes more time than just a function call. There are some parameters you can tweak in it, but I think that is the reason many games have their custom allocator, which malloc a huge chunk of memory and then keep it until the program exists.
- reality_czech 13y agoSome malloc() implementations return memory to the OS during free(). Many don't. For example, tcmalloc in its default configuration never returns memory to the OS. Also, what is "really slow" in the context of nethack? I'm willing to bet that you could malloc and free till the cows come home and never even notice in nethack. I bet the whole program doesn't take up more than a few megs of memory anyway.
- dllthomas 13y agoYes. For most applications, malloc is fine and when you want to reduce mallocs (pushing them out of performance critical code) usually pushing stuff up the stack is the way to go. That said, in development where C is really the right answer, malloc being a bad choice (and/or entirely unavailable, as in some embedded work) is far more common than in other programming - I think it's still a minority, though.
- dllthomas 13y ago"The problems that Nethack is having are basically self-inflicted. They opted to use setjmp and longjmp to emulate exceptions. So they don't have a good way of cleaning up things they malloc'ed. setjmp and longjmp are basically a way of implementing a cross-function "goto". it's just as bad as it sounds. Not to mention, they use a lot of functions like sprintf that have basically been banned by everyone else in the world. Hopefully they're not using gets()..." Not that I'd actually recommend it without significantly more investigation, but it's occurred to me that one could probably build a usable and reasonably safe framework around setjmp and longjmp where when you setjmp you create a context with which you can register cleanup actions (possibly coupled with a region allocator) to be run when something longjmps. I'm not actually sure the kind of constraints that would motivate this, though, without a clearer picture of what the code would look like.
- aidenn0 13y agoThough not what it's designed for, halloc[1] Is similar to what you are talking about; if each function manually allocated its locals with halloc, and used the parent function as the parent allocator, then you would get an unbroken tree, and would free all the children upon returning from the function that had called setjmp(). [1] http://swapped.cc/#!/halloc http://swapped.cc/#!/halloc
- dllthomas 13y agoYeah, for sure. Wouldn't allow for cleanup of non-memory resources, though, so far as I can tell.