4

Recently, I became interested in tracking memory allocation and deallocation. When overloading the new and delete operators, I found that the C++ standard library sometimes calls the overloaded operators and sometimes allocates memory using other methods. (Probably std::allocator.) For instance, std::string seems not to use new. Although, std::vector seems to call new when push_back is called. This is surprising since I would think the standard library would have a uniform policy to manage memory allocation.

When does the standard library choose to new vs std::allocator? Why?

  • 7
    What makes you think that `std::string` doesn’t (indirectly) call `new`? What makes you think that `std::allocator` doesn’t use `new`, or that `std::vector` doesn’t use `std::allocator`? Are you aware of the [short string optimization](https://stackoverflow.com/questions/10315041/meaning-of-acronym-sso-in-the-context-of-stdstring)? – Sneftel Jan 12 '22 at 09:08
  • 1
    First of all, you should publish your code you used for testing. For example, we must be sure that std::string wasn't allocated on stack (heap is not used) or no copy was created. – Damir Tenishev Jan 12 '22 at 09:08
  • 2
    AFAIK, `std::allocator` allocates memory with `operator new` as well. Anyway, as already noted, you are likely a victim of SSO. This means that `std::string` does not need to allocate memory for short strings up to some limit (usually 15 or 22 characters on a 64-bit architecture). – Daniel Langr Jan 12 '22 at 09:15
  • 1
    `std::allocator` (the templated allocator that standard containers use by default) use `::operator new(size_t)` or (since C++17) `::operator new(std::size_t, std::align_val_t)`. It is unspecified when or how that function is called (which allows the containers and allocators to tailor strategies for how they allocate and manage memory). – Peter Jan 12 '22 at 09:16
  • Yes, I was forcing the copy constructor to be called during testing. SSO was preventing the operator from being called. Thanks @Sneftel. – Moss Richardson Jan 12 '22 at 10:04
  • The reason `std::allocator` was introduced was old times when x86 processor had two types of pointers near and far. This might be helpful: https://youtu.be/LIb3L4vKZ7U – Marek R Jan 12 '22 at 10:14

1 Answers1

1

The standard containers will use the allocator provided to them to allocate dynamic memory. By default, that is std::allocator.

For most other dynamic memory uses in the standard library, the standard doesn't specify how the implementation should acquire memory, and the implementation has the freedom to do what they want.


As for tracking memory allocations, I recommend wrapping malloc.

eerorika
  • 232,697
  • 12
  • 197
  • 326