简单的学习问题。是否在C ++标准中指定了std类如何分配内存?我认为在内部,所有分配都会转发到new
/ new[]
。我对容器,std :: function和lambdas完成的分配特别感兴趣。
答案 0 :(得分:3)
标准库容器采用分配器模板参数,该参数用于控制内存的分配方式。默认情况下,他们使用std::allocator<T>
。 std::allocator<T>
有一个成员函数std::allocator<T>::allocate()
:
通过调用
为未初始化的存储分配n * sizeof(T)
::operator new(std::size_t)
个字节
同样,有std::allocator<T>::deallocate()
函数调用operator delete(void *)
。
std::function
std::function
有several constructors,其中一些允许您指定用于其内部分配的分配器对象。如果您没有指定,则会使用std::allocator
。
我不确定你希望用lambdas做什么分配。声明lambda时,编译器会在其operator()
中实现lambda的场景后面合成一个未命名的仿函数类型。如果从本地范围捕获任何变量,那些变量只会成为该类型定义的一部分,增加lambda类型的大小,但不需要任何动态分配;捕获的变量只是lambda未命名类型的成员。如果你要将lambda分配给类似std::function
的东西,那么std::function
可以进行动态分配以适应lambda增加的大小。
答案 1 :(得分:1)
标准库中的类通常是模板,可以使用特定的分配器来满足特殊需求。默认情况下,他们使用使用std::allocator
和operator new
的标准分配器(operator delete
):
20.7.9.1分配者成员[allocator.members]
...
pointer allocate(size_type n, allocator<void>::const_pointer hint = 0);
...
备注:存储是通过调用:: operator new(std :: size_t)(18.6.1)获得的,但未指定 调用此函数的时间或频率......void deallocate(pointer p, size_type n);
...
备注:使用:: operator delete(void *,std :: size_t)(18.6.1),但是当这个没有指定时 函数被调用。
调用运算符new和delete时未指定的事实允许实现缓存未使用的内存块,这是出于性能原因。
答案 2 :(得分:1)
标准容器接受作为分配器的模板化参数。默认情况下,每个标准容器的分配器都是std::allocator<T>
类型(例如std::vector<T>
的默认分配器类型为std::allocator<T>
)。 std::allocator
使用函数::operator new(size_t)
来分配原始内存。
典型新表达式(例如new Type
形式)的部分工作方式是调用函数::operator new(size_t)
。但是,默认分配器不需要使用这样的新表达式。
分配器的部分接口是提供成员函数construct(pointer p, const_reference val)
。 std::allocate<T>
的此成员函数返回new((void *)p) T(val)
(有时将其描述为展示位置新表达式)。
不要求非默认分配器(例如程序员提供的分配器类型而不是默认分配器)使用::operator new()
或新表达式。