5 ms·
> manually calling malloc and free is ridiculous in 2022 Why though? I use C++ and I use a variation of malloc and free all the time. The arguments I hear aga
by _gabe_ 4y ago
> manually calling malloc and free is ridiculous in 2022
Why though?
I use C++ and I use a variation of malloc and free all the time. The arguments I hear against malloc is:
1. You'll leak memory.
This is super easy to solve in literally 300 lines of code or less. Just have a vector of your memory allocations in debug mode. Then call a custom allocator and free function that adds an allocation and removes an allocation from this list. At the end of the program, print out any allocations that are in the list that never got freed. You can use macros to print the exact file and line number that allocated the memory and then fix it very quickly.
2. It's not typesafe.
So just use new if you're really concerned with type safety and then overload the operator to get the benefits I described above.
3. It's unsafe.
How is this any more unsafe than RAII? Aren't there still the same risks involved?
4. Nullptr exceptions.
Once again, same problem with smart pointers. Technically if you're not transferring ownership you should be passing a const reference or a raw pointer rather than a smart pointer anyways. So the end result is the same.
Maybe I'm missing some huge thing, but I have not heard any convincing argument for using shared pointers over malloc. (And yes I know you should really use new if you're not using POD because of constructors and all that stuff, but I'm equating new and malloc for brevity).
Lastly, I've found that when I use shared pointers I get lulled into a false sense of security and get sloppy. It's a good thing to really think about why you're making a specific memory allocation. Doing it manually forces you to consider whether there's a better option like static local storage or something. In addition, as long as you have a memory tracker implemented like my answer to 1, you never have to spend time worrying about memory. Just today, I forgot to free some memory and I was immediately notified when I ran my program and it printed a warning after I closed it with the leak. I cleaned it up in 5 minutes, end of story.
Edit: I forgot to mention, what's the one huge pro to using new/delete or malloc/free over smart pointers? Explicit control over when memory gets allocated and deallocated. If you use smart pointers everywhere, won't you eventually have the same issue as GC? They go out of scope at random points in your programs lifetime, and you get "random" lag spikes from memory cleanup. The whole point of using C++ is to have control over when this stuff happens! If you don't care when it happens, why not use the GC?
- lelanthran 4y ago> 1. You'll leak memory. > > This is super easy to solve in literally 300 lines of code or less. Just have a vector of your memory allocations in debug mode. Then call a custom allocator and free function that adds an allocation and removes an allocation from this list. At the end of the program, print out any allocations that are in the list that never got freed. You can use macros to print the exact file and line number that allocated the memory and then fix it very quickly. I've got similar macros for C, but it is still less work to simply use valgrind.
- _gabe_ 4y agoNice :) Valgrind is easier, but for real-time applications I've found that it takes a huge performance hit for some reason, at least the last time I used it.
- lelanthran 4y ago> Valgrind is easier, but for real-time applications I've found that it takes a huge performance hit for some reason, at least the last time I used it. It does, because it runs the app in an emulator. What I did in the past (around 2005) was to write replacement malloc/calloc/realloc/free calls, put them into a libmymalloc.so, and then set LD_PRELOAD to point to libmymalloc.so. This way I could switch between my malloc routines and the system malloc routines without recompiling the program.
- jbboehr 4y agotalloc[0] is a pretty cool allocator that also has the ability to do this sort of thing. [0]: https://talloc.samba.org/talloc/doc/html/index.html https://talloc.samba.org/talloc/doc/html/index.html
- jcelerier 4y ago> How is this any more unsafe than RAII? Aren't there still the same risks involved? std::vector<int> allocation_counts; auto get_mem(int n) { auto* memory = your_malloc(n); allocation_counts.push_back(n); return memory; } This function has a trivial leak of "memory" that an RAII version wouldn't have, can you see it?