C++标准库中的内存分配

4

最近,我对跟踪内存分配和释放产生了兴趣。当重载new和delete运算符时,我发现C++标准库有时会调用重载运算符,但有时会使用其他方法来分配内存(可能是std::allocator)。例如,std::string似乎没有使用new。尽管std::vector在调用push_back时似乎会调用new。这很令人惊讶,因为我认为标准库应该有一致的内存分配管理策略。

标准库何时选择使用new,何时选择使用std::allocator?为什么?


7
你认为std::string不会(间接)调用new的依据是什么?你认为std::allocator不会使用new,或者std::vector不会使用std::allocator的依据又是什么?你知道短字符串优化吗? - Sneftel
1
首先,您应该发布用于测试的代码。例如,我们必须确保 std::string 没有在堆栈上分配(没有使用堆),也没有创建任何副本。 - Damir Tenishev
2
据我所知,std::allocator 也使用 operator new 来分配内存。无论如何,正如已经指出的那样,您很可能是 SSO 的受害者。这意味着 std::string 不需要为短字符串(通常在 64 位架构上为 15 或 22 个字符)分配内存。 - Daniel Langr
1
std::allocator(标准容器默认使用的模板化分配器)使用 ::operator new(size_t) 或(自 C++17 起)::operator new(std::size_t, std::align_val_t)。该函数何时以及如何调用是未指定的(这允许容器和分配器为它们分配和管理内存的策略进行定制)。 - Peter
是的,在测试期间我强制调用了复制构造函数。SSO 防止了操作符被调用。感谢 @Sneftel。 - Moss Richardson
std::allocator 被引入的原因是在旧时代,x86 处理器有两种指针类型:near 和 far。这个视频可能会有所帮助:https://youtu.be/LIb3L4vKZ7U - Marek R
1个回答

1
标准容器将使用提供给它们的分配器来分配动态内存。默认情况下,使用的是std::allocator
对于标准库中的大多数其他动态内存使用,标准并未规定实现应如何获取内存,实现有自由进行操作。
至于跟踪内存分配,建议包装malloc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接