102

Why is the first C++ (m)allocation always 72 KB?

This is compiler specific and cannot be generalised as C++.

6 hours agopjmlp

Well, yes, but still quite interesting, IMHO. It's not like GCC is one of the least used compilers.

5 hours agozabzonk

Yeah, but that isn't C++ in isolation, thus the tile is incorrect.

5 hours agopjmlp

Article has been updated

> EDIT (March 1, 2026): I updated the title to to clarify that this observation is specific to my environment. The original title may have implied a universal behavior, which isn’t the case. Thanks for the feedback!

3 hours agoappreciatorBus

And C++ library specific as well. Perhaps even more so.

6 hours agocompiler-guy

Reading this was a good reminder not to be intimidated by assumptions about complexity. (Without giving it much thought) I would have assumed that it would be hard to replace malloc for such fundamental applications as ls, but it's surprisingly simple.

3 hours agojebarker

There's usually an easy-ish way to override malloc/calloc/realloc/free on Unix, as it's very useful to do when debugging issues or just to collect allocation metrics.

In ELF objects (i.e. on Linux) this is usually done with the "Weak" symbol binding. This is an optional flag for symbols in ELF format that let you override a symbol by providing a competing non-weak symbol, which the linker will prefer when there is a conflict. https://en.wikipedia.org/wiki/Weak_symbol

You can see the list of Weak symbols by looking for a 'W' in the output of `nm` on linux hosts.

2 hours agosyncsynchalt

Huh. Why is this emergency pool not statically allocated? Is it possible to tune the size of this pool on libc++ startup somehow? Because otherwise it absolutely should've been statically allocated.

7 hours agoJoker_vD

I did mention it briefly in the post, but you can opt-in for a fixed-size statically allocated buffer by configuring libstdc++ with --enable-libstdcxx-static-eh-pool. Also, you can opt-out of the pool entirely by configuring the number of objects in the pool to zero with the environment variable GLIBCXX_TUNABLES=glibcxx.eh_pool.obj_count=0.

7 hours agojoelsiks

I wonder why it’s opt-in. Maybe it’s part of the whole “you only pay for what you use” ethos, i.e. you shouldn’t have to pay the cost for a static emergency pool if you don’t even use dynamic memory allocation.

5 hours agoninkendo

I would like the see the source code for libmymalloc.so, however, I don't see anything in the blog post. Nor do I see anything in his GitHub profile: https://github.com/jsikstro

Also, I cannot find his email address anywhere (to ask him to share it on GitHub).

Am I missing something?

9 hours agothrowaway2037

The exact implementation of mymalloc isn't relevant to the post. I have an old allocator published at https://github.com/joelsiks/jsmalloc that I did as part of my Master's thesis, which uses a similar debug-logging mechanism that is described in the post.

8 hours agojoelsiks

dlsym() with the RTLD_NEXT flag basically:

https://catonmat.net/simple-ld-preload-tutorial-part-two

There's actually a better way to hook GNUs malloc:

https://www.man7.org/linux/man-pages/man3/malloc_hook.3.html

This is better because you can disable the hook inside the callback, and therefore use malloc within your malloc hook (no recursion)

But you can't use this mechanism before main()

8 hours agonly

    The use of these hook functions is not safe in multithreaded
    programs, and they are now deprecated.  From glibc 2.24 onwards,
    the __malloc_initialize_hook variable has been removed from the
    API, and from glibc 2.34 onwards, all the hook variables have been
    removed from the API.  Programmers should instead preempt calls to
    the relevant functions by defining and exporting malloc(), free(),
    realloc(), and calloc().
7 hours agoJoker_vD

Yeah. Shame though because it gave you the option to control exactly when you hooked and didn't hook, which let stop and start debugging allocations based on arbitrary triggers.

The global variable approach was very useful and pretty low overhead.

6 hours agonly

You can still override malloc and call __libc_malloc if you do not want to bother with dlsym/RTLD_NEXT. These function aliases are undocumented, but for a quick experiment, that shouldn't matter.

3 hours agofweimer

If you only wanted to observe the behavior the post is discussing, it seems like `ltrace -e malloc` is a lot easier.

4 hours agojeffbee

I think you should read up on what "always" means.

5 hours agoaliveintucson

> TLDR; The C++ standard library sets up exception handling infrastructure early on, allocating memory for an “emergency pool” to be able to allocate memory for exceptions in case malloc ever runs out of memory.

Reminds me of Perl's $^M: https://perldoc.perl.org/variables/$%5EM

In Perl you can "hand-manage" that. This line would allocate a 64K buffer for use in an emergency:

    $^M = 'a' x (1 << 16);
5 hours agoznpy
[deleted]