标签: allocator

C++分配器和内存池所有权

我对某些事感到困惑.假设我有一个任意的C++分配器 - 比方说,像这样:

template<class T>
struct my_allocator
{
    template<class Other>
    struct rebind { typedef my_allocator<Other> other; };

    // [other members here]
};
Run Code Online (Sandbox Code Playgroud)

现在考虑以下代码(请阅读评论):

typedef my_allocator<int> Alloc;
Alloc alloc = get_my_allocator();  // assume this works properly

long *const p = Alloc::rebind<long>::other(alloc).allocate(1, NULL);
// Notice that the rebound allocator for 'long' is now destroyed

// Can a NEW rebound allocator for 'long' deallocate the memory from the old one?
Alloc::rebind<long>::other(alloc).deallocate(p, 1);
// i.e., does the 'int' allocator 'alloc' keep alive the 'long' …
Run Code Online (Sandbox Code Playgroud)

c++ memory-management allocator c++11

14
推荐指数
1
解决办法
595
查看次数

allocator construct()默认初始化而不是值初始化吗?

作为这个问题的后续,默认的allocator(std::allocator<T>)需要construct按如下方式实现(根据[default.allocator]):

template <class U, class... Args>
void construct(U* p, Args&&... args);
Run Code Online (Sandbox Code Playgroud)

效果:::new((void *)p) U(std::forward<Args>(args)...)

也就是说,始终是值初始化.结果是std::vector<POD> v(num),对于任何pod类型,将值初始化num元素 - 这比默认初始化num元素更昂贵.

为什么没有 std::allocator提供默认初始化的额外过载?就是这样的(借用凯西):

template <class U>
void construct(U* p) noexcept(std::is_nothrow_default_constructible<U>::value)
{
    ::new(static_cast<void*>(p)) U;
}
Run Code Online (Sandbox Code Playgroud)

是否有理由在呼叫案例中更喜欢值初始化?对我来说这似乎令人惊讶,这打破了通常的C++规则,我们只支付我们想要使用的内容.


我认为这样的改变是不可能的,因为目前std::vector<int> v(100)会给你100 0秒,但我想知道为什么会这样......因为人们可以很容易地std::vector<int> v2(100, 0)以同样的方式要求有差异之间new int[100]new int[100]{}.

c++ vector allocator language-lawyer c++11

14
推荐指数
1
解决办法
537
查看次数

用于字符串的容量值

在C++标准库中,std::string有一个公共成员函数capacity(),它返回内部分配存储的大小,一个大于或等于字符串中字符数的值(根据此处).这个值可以用于什么?它与自定义分配器有关吗?

c++ string capacity allocator

13
推荐指数
2
解决办法
465
查看次数

在C++ 0x中allocator_traits <T>的目的是什么?

为什么不是标准的C++ 03接口来查询C++ 0x中使用的分配器的成员类型?成员类型不足的用例有哪些?

c++ traits allocator c++11

13
推荐指数
2
解决办法
3136
查看次数

为什么c ++中的allocator为void类型提供特化

我注意到c ++中的allocator为void类型提供了特化.这样做有什么特别的目的吗?为void类型分配内存没有意义,对吧?

c++ stl allocator

12
推荐指数
1
解决办法
901
查看次数

为什么元组有uses_allocator但是对没有?

std::scoped_allocator_adaptor到目前为止,在尝试使用gcc 4.7.0中实现的C++ 11时,我注意到C++ 11 FDIS定义了std::uses_allocatorfor tuples(20.4.2.8[tuple.traits])的特化,但是没有定义对,尽管出于所有其他目的,对看起来和行为就像元组(他们的专长std::get,std::tuple_size等等).

在进一步阅读中,介绍这些东西的N2554也定义了对的allocator_arg构造函数和特化uses_allocator(第23-24页).

他们为什么要成对掉队?有没有其他方法可以使用我看不到的,或者这是否有一些赞成元组的对折旧?

我的测试代码是:

// myalloc is like std::allocator, but has a single-argument
// constructor that takes an int, and has NO default constructor
typedef std::vector<int, myalloc<int>> innervector_t;
typedef std::tuple<int, innervector_t> elem_t;
typedef std::scoped_allocator_adaptor<myalloc<elem_t>, myalloc<int>> Alloc;
Alloc a(1,2);
std::vector<elem_t, Alloc> v(a);
v.resize(1);                  // uses allocator #1 for elements of v
// the following line fails to compile if pair is …
Run Code Online (Sandbox Code Playgroud)

c++ allocator c++11

12
推荐指数
1
解决办法
697
查看次数

c ++ Vector,每当它在堆栈上扩展/重新分配时会发生什么?

我是C++的新手,我在项目中使用了矢量类.我发现它非常有用,因为我可以有一个数组,只要有必要就会自动重新分配(例如,如果我想推送一个项目并且向量已达到它的最大容量,它会重新分配自己,为操作系统提供更多的内存空间),所以对向量元素的访问非常快(它不像列表,要达到"第n"元素,我必须通过"n"个第一个元素).

我发现这个问题非常有用,因为当我想将我的向量存储在堆/堆栈上时,他们的答案完全解释了"内存分配器"是如何工作的:

[1] vector<Type> vect;
[2] vector<Type> *vect = new vector<Type>;
[3] vector<Type*> vect;
Run Code Online (Sandbox Code Playgroud)

然而,怀疑是困扰我一段时间,我找不到它的答案:每当我构建一个向量并开始推入大量项目时,它将达到向量将满的时刻,因此继续增长它需要重新分配,将自身复制到一个新位置,然后继续push_back项(显然,这个重新分配它隐藏在类的实现上,所以它对我来说是完全透明的)

好吧,如果我在堆上创建了向量[2],我没有想象可能发生的事情:类向量调用malloc,获取新空间然后将自身复制到新内存中,最后删除调用free的旧内存.

然而,当我在堆栈上构造一个向量时,面纱会隐藏正在发生的事情[1]:当向量必须重新分配时会发生什么?AFAIK,无论何时在C/C++上输入一个新函数,计算机都会查看变量声明,然后展开堆栈以获得放置这些变量所需的空间,但是当你在堆栈中分配更多空间时功能已在运行.类向量如何解决这个问题?

c++ stack vector allocator

12
推荐指数
3
解决办法
8856
查看次数

Stephen Lavavej的Mallocator在C++ 11中是一样的吗?

8年前,Stephen Lavavej发表了这篇博客文章,其中包含一个名为"Mallocator"的简单分配器实现.从那时起,我们已经过渡到C++ 11时代(很快就会出现C++ 17)......新的语言特征和规则是否会影响Mallocator,或者它仍然是相关的?

c++ containers allocator c++-standard-library c++11

12
推荐指数
1
解决办法
2009
查看次数

unordered_set 可以为节点和存储桶列表使用不同的分配器吗?

我想将 astd::pmr::unordered_map与 a一起使用std::pmr::monotonic_buffer_resource。两者配合得很好,因为集合的节点是稳定的,所以我不会通过重新分配在缓冲区资源中创建很多漏洞:

 std::pmr::monotonic_buffer_resource res;
 std::pmr::unordered_set<T> set(&res);
Run Code Online (Sandbox Code Playgroud)

也就是说,除了桶列表,当集合超过max_load_factor(). 假设我无法reserve()摆脱这种情况,并且我实际上关心自增长以来旧桶列表留下的缓冲区资源中的漏洞,我有什么选择?

如果我知道它unordered_set是作为 实现的std::vector<std::forward_list>,就像在(某些版本的)MSVC 中一样,那么我应该能够使用 ascoped_allocatorvectorforward_list. 但)我不能依赖unordered_set是一个vector<forward_list>可移植的代码和b)scoped_allocator是一个Allocator,而monotonic_buffer_resourcememory_resource,阻抗失配,这将使非常复杂的初始化。

或者我可以根据请求的大小编写一个switch_memory_resource委托给其他memory_resources 的 s 。然后,我可以使用monotonic_buffer_resource与节点大小匹配的请求(但是,我不能,可移植地,知道)以及default_memory_resource()其他所有内容。我可能会做出有根据的猜测,节点最多为sizeof(struct {void* next; size_t hash; T value;}),通过将其乘以 2 来添加一些误差幅度,并将其用作两个memory_resources之间的截止点,但我想知道是否有更简洁的方法?

c++ allocator unordered-set c++17 c++pmr

12
推荐指数
2
解决办法
283
查看次数

调试时 GCC 中的自定义 C++ 分配器太慢。有解决办法吗?

我正在努力解决自定义分配器的性能问题。我的问题是关于调试版本。

通常情况下,如果只有一点点下降我并不介意。但目前我正在以 4fps 播放某些内容,而如果没有自定义分配器,则播放速度为 60fps(并且可能会更快)。这使得软件开发变得更加困难。

我一直把它确定下来......基本上继承了标准分配器

请参阅“quick-bench.com”的以下结果 https://quick-bench.com/q/ep3uyYNK6rh_6f8AGAP0zIAflAA

这是一张图片: 在此输入图像描述

蓝色条很简单:

int main() {
    std::vector<uint8_t, std::vector<uint8_t>::allocator_type> buffer;
    buffer.reserve(numBytes);
    buffer.resize(numBytes);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

黄色条:

template<typename T>
class CustomAllocatorType : public std::vector<uint8_t>::allocator_type {};

int main() {
    std::vector<uint8_t, CustomAllocatorType<uint8_t>> buffer;
    buffer.reserve(numBytes);
    buffer.resize(numBytes);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用以下内容封装自定义分配器:

#pragma GCC push_options
#pragma GCC optimize ("-O3")
// ....
#pragma GCC pop_options
Run Code Online (Sandbox Code Playgroud)

没有任何效果。我想我需要对向量实例本身执行此操作,但我不想走那么远......

有谁知道这个问题的解决方案?

c++ gcc allocator c++20

12
推荐指数
1
解决办法
493
查看次数