> Not only that, mfree() receives the size of the object it is deallocating, as it should.
I've always thought that one of the biggest tiny mistakes in the history of this industry. It means, more or less, that you're forcing the memory allocator to keep track of these sizes when it shouldn't have to. There's virtually no sensible case where the person calling free() doesn't know the size of the allocation, so now we're keeping that book-keeping twice, in "user-space" and inside the memory allocator. Like, think about the cases when you'd call malloc:
* For allocating a single object of type T, the size is just `sizeof(T)`, so you can just pass that to free()
* For allocating an array of objects, the size is `count
* sizeof(T)`, and I can't think of a single time where you DON'T know what `count` is. It's either statically sized (in which case it's just a constant), or if you have a dynamically growing array, you need to keep track of the reserved space to know when you reallocate. If nothing else, you need it for bounds-checking.
* For chunks of raw memory, you also presumably know when deallocating what the size of the raw memory you allocated is, for the same reasons as the previous point. Like, just having a raw char* pointer lying around with no size information is just terrible C practice.
If you truly don't know the size of your allocation (very hard to imagine when this would ever happen), you should be forced on the user-side to keep track of it somehow, not delegate that to the allocator.
It's a tiny amount of overhead, but it's for EVERY SINGLE MEMORY ALLOCATION since like 1975. Imagine how many times malloc() and free() has called since then! How much electricity, CPU usage, and memory has been wasted! It boggles the mind!
"void*" sadly exists, and there are a lot of edge cases.
I tried using TCMalloc with rustc, and it segfaulted. Rust knows the sizes of its allocations, but things can still go wrong at the allocator boundary.
Size should be an optimization hint, not a correctness requirement. Otherwise, it's just another security pitfall
I don't agree. Zig allocators require the size of the allocation (technically they take a slice, but a slice is ptr + size), as does the C++ polymorphic allocator, as does many allocator interfaces in many libraries (see for instance the allocator interface in Lua, my personal favorite C interface for memory allocation [0]). Clearly having it as a correctness requirement works just fine.
The sbrk system call in linux is still available to get more heap from the operating system. So, memory is still allocated in a linear fasion and never released again. Maybe now functions like mmap change this. I used sbrk to implement malloc for a very limited standard libary implementation.
I don't associate with the author that well here because I'm not hyped about 'arena allocators' and I don't really care that free doesn't receive a size. I think the interface was okay.
Also 'arena allocators' (this meant something different like 20 years ago so I think the name just got rebranded) are not that good, they make some things easier and improve performance sometimes, they also are liable to use more memory and cause more fragmentation if not used with care. That is one of the many reasons why we slowly evolved away from the old linear allocators, but also because we just wanted a simple and flexible interface to hide complexity.
When I was a college student (15 years ago), I first encountered C through A Book on C, and C seems like a language that is simple but can really do a lot. Looking at how old this language is, and how many concepts already used in modern languages were tried during its development history, is surprising. It's surprising that the concepts I thought were modern techniques today were already being tried decades ago—that is, before I was even born.
It's amazing that a method like the Bump Allocator was already tried.
How were the senior programmers able to do all of this? I'm just amazed.
> How were the senior programmers able to do all of this? I'm just amazed.
I think it has to do with a combination of factors that changed over the years. First of all computer science was viewed more theoretical and less applied at that time. A computer scientist would be interested in optimizing a certain algorithm instead of making an app.
Secondly the systems in that time where less complex meaning it was easier to understand and experiment with fundamental parts of the computer.
Lastly at that time "programming" was closer to the metal so a average computer scientist at that time would likely have more knowledge of the deep internals compared to an average programmer today.
> C seems like a language that is simple but can really do a lot
I like to borrow a phrase from the realm of gaming: "easy to learn hard to master".
if you write your program first with pencil and paper u'll be amazed at what you can do yourself.
most people open an ide and start coding, or write some basic diagrams to get an overview/mental model. Back in the day any bitnlarge program would take hours to compile so really u did not want to have any bug or typo just to sit for hours until a compile error or logic mistake. Take it even further back to days before C and that is even more needed.
a lot of high level modern languages seem to alleviate that need, likely so that enterprise software can be written a bit faster because the features need to arrive faster.
still in more modern languages i'd recommend starting with pencil and paper, write most of it if not the whole thing out. u'll find much nicer patterns and will save yourself a bunch of refactoring. even for small programs.
When I was at school, I used to program on paper like this (due to not having a computer during class). It was accidentally a great exercise, that I think everyone should try. Because of it, I find myself writing mostly bug-free code on my first try these days (my bugs tend to happen on interactions between parts of a system I designed separately).
The answer is more likely that modern students just don't learn their history and think they've cleverly come up with something new (after all, it's new to them). If you've learned your history you would understand it has ever been thus. Aristotle and Hesiod complained about it, and Aristophanes even wrote a play satirizing it that could be performed today and it would still be relevant.
They came up with bump allocators because they had a blank mind, devoid of today's complexity. You would also come up with it if you were sat in front of a terminal with no internet. Ask anyone old enough.
Maybe the midterms caused you to refresh the front page more often so that you noticed this post before it had been there long enough to get upvoted a lot. (The minimum to get on the front page is 2 upvotes.)
According to your ref, it entered the front page at a "Top" rank of 8 at 8:10:00Z, when it had 2 upvotes. Just as I told you. (Did you confuse the "New" rank for the front page?)
> Not only that, mfree() receives the size of the object it is deallocating, as it should.
I've always thought that one of the biggest tiny mistakes in the history of this industry. It means, more or less, that you're forcing the memory allocator to keep track of these sizes when it shouldn't have to. There's virtually no sensible case where the person calling free() doesn't know the size of the allocation, so now we're keeping that book-keeping twice, in "user-space" and inside the memory allocator. Like, think about the cases when you'd call malloc:
* For allocating a single object of type T, the size is just `sizeof(T)`, so you can just pass that to free()
* For allocating an array of objects, the size is `count
* sizeof(T)`, and I can't think of a single time where you DON'T know what `count` is. It's either statically sized (in which case it's just a constant), or if you have a dynamically growing array, you need to keep track of the reserved space to know when you reallocate. If nothing else, you need it for bounds-checking.
* For chunks of raw memory, you also presumably know when deallocating what the size of the raw memory you allocated is, for the same reasons as the previous point. Like, just having a raw char* pointer lying around with no size information is just terrible C practice.
If you truly don't know the size of your allocation (very hard to imagine when this would ever happen), you should be forced on the user-side to keep track of it somehow, not delegate that to the allocator.
It's a tiny amount of overhead, but it's for EVERY SINGLE MEMORY ALLOCATION since like 1975. Imagine how many times malloc() and free() has called since then! How much electricity, CPU usage, and memory has been wasted! It boggles the mind!
"void*" sadly exists, and there are a lot of edge cases.
I tried using TCMalloc with rustc, and it segfaulted. Rust knows the sizes of its allocations, but things can still go wrong at the allocator boundary.
Size should be an optimization hint, not a correctness requirement. Otherwise, it's just another security pitfall
I don't agree. Zig allocators require the size of the allocation (technically they take a slice, but a slice is ptr + size), as does the C++ polymorphic allocator, as does many allocator interfaces in many libraries (see for instance the allocator interface in Lua, my personal favorite C interface for memory allocation [0]). Clearly having it as a correctness requirement works just fine.
[0]: https://www.lua.org/manual/5.4/manual.html#lua_Alloc
The sbrk system call in linux is still available to get more heap from the operating system. So, memory is still allocated in a linear fasion and never released again. Maybe now functions like mmap change this. I used sbrk to implement malloc for a very limited standard libary implementation.
I don't associate with the author that well here because I'm not hyped about 'arena allocators' and I don't really care that free doesn't receive a size. I think the interface was okay.
Also 'arena allocators' (this meant something different like 20 years ago so I think the name just got rebranded) are not that good, they make some things easier and improve performance sometimes, they also are liable to use more memory and cause more fragmentation if not used with care. That is one of the many reasons why we slowly evolved away from the old linear allocators, but also because we just wanted a simple and flexible interface to hide complexity.
When I was a college student (15 years ago), I first encountered C through A Book on C, and C seems like a language that is simple but can really do a lot. Looking at how old this language is, and how many concepts already used in modern languages were tried during its development history, is surprising. It's surprising that the concepts I thought were modern techniques today were already being tried decades ago—that is, before I was even born.
It's amazing that a method like the Bump Allocator was already tried.
How were the senior programmers able to do all of this? I'm just amazed.
I think it has to do with a combination of factors that changed over the years. First of all computer science was viewed more theoretical and less applied at that time. A computer scientist would be interested in optimizing a certain algorithm instead of making an app.
Secondly the systems in that time where less complex meaning it was easier to understand and experiment with fundamental parts of the computer.
Lastly at that time "programming" was closer to the metal so a average computer scientist at that time would likely have more knowledge of the deep internals compared to an average programmer today.
I like to borrow a phrase from the realm of gaming: "easy to learn hard to master".
I have always thought about C being a language with "simple" syntax (but things like type declarations are hell), but very complicated semantics.
if you write your program first with pencil and paper u'll be amazed at what you can do yourself.
most people open an ide and start coding, or write some basic diagrams to get an overview/mental model. Back in the day any bitnlarge program would take hours to compile so really u did not want to have any bug or typo just to sit for hours until a compile error or logic mistake. Take it even further back to days before C and that is even more needed.
a lot of high level modern languages seem to alleviate that need, likely so that enterprise software can be written a bit faster because the features need to arrive faster.
still in more modern languages i'd recommend starting with pencil and paper, write most of it if not the whole thing out. u'll find much nicer patterns and will save yourself a bunch of refactoring. even for small programs.
When I was at school, I used to program on paper like this (due to not having a computer during class). It was accidentally a great exercise, that I think everyone should try. Because of it, I find myself writing mostly bug-free code on my first try these days (my bugs tend to happen on interactions between parts of a system I designed separately).
> It's amazing that a method like the Bump Allocator was already tried.
The old saying "Necessity is the mother of invention" applies. Smart people + system constraints => ingenuity.
The answer is more likely that modern students just don't learn their history and think they've cleverly come up with something new (after all, it's new to them). If you've learned your history you would understand it has ever been thus. Aristotle and Hesiod complained about it, and Aristophanes even wrote a play satirizing it that could be performed today and it would still be relevant.
They came up with bump allocators because they had a blank mind, devoid of today's complexity. You would also come up with it if you were sat in front of a terminal with no internet. Ask anyone old enough.
Never seen a 4 points story on the front page.
These are the misteries of HN.
I thought it was a mid-term election mystery
Maybe the midterms caused you to refresh the front page more often so that you noticed this post before it had been there long enough to get upvoted a lot. (The minimum to get on the front page is 2 upvotes.)
Not really, it was "sponsored" by HN very early.
Ref: https://news.social-protocols.org/stats?id=50362466
According to your ref, it entered the front page at a "Top" rank of 8 at 8:10:00Z, when it had 2 upvotes. Just as I told you. (Did you confuse the "New" rank for the front page?)
No, look at the "raw" rank. It's the one without HN/manual intervention.
It was catapulted to 8th rank while its "raw" was around 50th give or take.