4 ms·
> Try doing C with a garbage collector ... it's very liberating. > Do `#include <gc.h>` then just use `GC_malloc()` instead of `malloc()` and never free. Even
by enriquto 2y ago
> Try doing C with a garbage collector ... it's very liberating.
> Do `#include <gc.h>` then just use `GC_malloc()` instead of `malloc()` and never free.
Even more liberating (and dangerous!): do not even malloc, just use variable length-arrays:
void f(float *y, float *x, int n)
{
float t[n]; // temporary array, destroyed at the end of scope
...
}
This style forces you to alloc the memory at the outermost scope where it is visible, which is a nice thing in itself (even if you use malloc).
- kqr 2y agoAt first I really liked this idea, but then I realised the size of stack frames is quite limited, isn't it? So this would work for small data but perhaps not big data.
- enriquto 2y agoIn theory, this is a compiler implementation detail. The compiler may chose to put large stacks in the heap, or to not even use a stack/heap system at all. The semantics of the language are independent of that. In practice, stack sizes used to be quite limited and system-dependent. A modern linux system will give you several megabites of stack by default (128MB in my case, just checked in my linux mint 22 wilma). You can check it using "ulimit -all", and you can change it for your child processes using "ulimit -s SIZE_IN_KB". This is useful for your personal usage, but may pose problems when distributing your program, as you'll need to set the environment where your program runs, which may be difficult or impossible. There's no ergonomical way to do that from inside your C program, that I know of.
- dzdt 2y agoIts a giant peeve of mine that automatic memory management, in the C language sense of the resource being freed at the end of its lexical scope, is tied to the allocation being on the machine stack which in practice may have incredibly limited size. Gar! Why!?
- enriquto 2y agoAckshually, it has nothing to do with the C language. It's an implementation choice by some compilers. A conforming implementation could give you the whole RAM and swap to your stack.
- int_19h 2y agoYes, but does any implementation actually do that? AFAIK Ada is typically more flexible, but that has to do with the language actually giving you enough facilities to avoid heap allocations in more cases - e.g. you can not only pass VLAs into a function in Ada, but also return one from a function. So it becomes idiomatic, and compilers then have to support this (usually by maintaining a second "large" stack).
- duskwuff 2y agoIt isn't a practical pattern for anything beyond the most trivial applications. Consider what this would look like if you tried to write a text editor, for instance - if a user types a new line of text, where is the memory for that allocated?
- thodg 2y ago[dead]
- kqr 2y agoThose would be the difficult questions one would be forced to confront ahead of time with this technique. That's not a bug; it's a feature! Similar to what Ada does with access types which are lexically scoped.
- brucehoult 2y agoThe problem is that regardless of the amount of confrontation it does not have an answer for any infinite run time event-loop based program, other than "allocate all of memory into a buffer at startup and implement your own memory manager inside that". Which just punts the problem from a mature and tested runtime library to some code you just make up on the spot.
- int_19h 2y agoHeap was invented for a reason, and some tasks are naturally easier to model with it. The problem is that once it's there, people start using it as the proverbial hammer, and everything looks like a nail even if it isn't. Note though that ""allocate all of memory into a buffer at startup" is a lot more viable if you scope it not to the start of the app, but to the entrypoint of some code that needs to make a complicated calculation. It's actually not all that uncommon to need something heap-like to store temporary data as you compute - e.g. a list or map to cache intermediary results - but which shouldn't outlive the computation. Ada access types give you exactly that - declare them inside the top-level function that's your entrypoint, allocate as needed in nested functions as they get called, and know that it'll all be cleaned up once the top-level function returns.
- __turbobrew__ 2y agoYea, usually the stack ulimit is only a few KiB for non-root processes by default on linux. It is easy enough to increase, but it does add friction to using the software as it violates the default stack size limit on most linux installs. Not even sure why stack ulimit is a thing anymore, who cares if the data is on the stack vs the heap?
- mrheosuper 2y agoAs FW engineer, i do
- hdrz 2y agoC with dynamic arrays and classes? Object pascal says hello…