问题标签 [allocator]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
709 浏览

c++ - 是否存在在实例化时调整大小但避免 boost::dynamic_bitset<> 的额外分配调用的位集类?

是否有一个std::bitset<>在实例化时可以动态调整大小的方便模拟,但避免了所需的额外分配boost::dynamic_bitset<>

您可以通过执行以下操作在 C 中轻松创建动态大小的位集:

仅当您在编译时std::vector<std::bitset<bits>>知道时才能执行此操作。bits如果你使用std::vector<boost::dynamic_bitset<>>,那么你会看到一个额外的分配器调用。是否有一种折衷方案可以实现上述 C 代码的平衡?

例如,您可能有一些用于 std::vector<...> 的自定义分配器,它在每个之后留下一些额外的空间boost::dynamic_bitset<>并在那里分配m_block,尽管这可能仍然会花费您的指针m_block

0 投票
2 回答
614 浏览

c++ - Is there a C++ allocator that respects an overridden new/delete?

I'm implementing a resource-allocating cloning operation for an array of type T. The straightforward implementation uses new T[sz] followed by a std::copy call from the source into the new array. It walks memory twice.

I'd like to allocate raw memory and then use std::uninitialized_copy so I only walk memory once for performance reasons. I know how to accomplish this when a custom allocator is used (Allocator.allocate followed by std::uninitialized_copy), and I know how to accomplish this using std::allocator (which employs ::operator new following lib.allocator.members in section 20.4.1.1 of the specification). My concern is that a std::allocator-based approach seems wrong for types T where T::operator new has been defined. I know I can detect such a situation using Boost.TypeTraits' has_new_operator.

Is there a simple, standards-compliant way to allocate-and-then-initialize raw memory in a fashion that will respect an overridden new (and does so passing over memory only once)? If not, does using SFINAE to dispatch between an implementation employing std::allocator and one using the overridden operator new seem reasonable? FWIW, grepping through Boost does not show such a use of the has_new_operator trait.

Thanks, Rhys

0 投票
3 回答
3946 浏览

c++ - 增加容量时,std::vector *有*移动对象吗?或者,分配器可以“重新分配”吗?

一个不同的问题激发了以下想法:

增加容量时是否std::vector<T> 必须移动所有元素?

据我了解,标准行为是底层分配器请求新大小的整个块,然后移动所有旧元素,然后销毁旧元素,然后释放旧内存。

考虑到标准分配器接口,这种行为似乎是唯一可能的正确解决方案。但我想知道,修改分配器以提供一个reallocate(std::size_t)返回 apair<pointer, bool>并可以映射到底层的函数是否有意义realloc()?这样做的好处是,如果操作系统实际上可以扩展分配的内存,那么根本不需要移动。布尔值将指示内存是否已移动。

(std::realloc()可能不是最好的选择,因为如果我们不能扩展,我们不需要复制数据。所以实际上我们宁愿想要类似的东西extend_or_malloc_new()编辑:也许基于is_pod-trait 的专业化可以让我们使用实际的realloc,包括它的按位复制。只是一般情况下。)

这似乎是一个错失的机会。最坏的情况,你总是可以实现reallocate(size_t n)as return make_pair(allocate(n), true);,所以不会有任何惩罚。

是否有任何问题使此功能不适合或不适合 C++?

也许唯一可以利用这一点的容器是std::vector,但话又说回来,这是一个相当有用的容器。


更新:一个小例子来澄清。当前resize()

新实现:

0 投票
1 回答
295 浏览

c++ - 使用分配器概念时如何避免堆栈上的临时对象?

以下代码尝试创建二叉树的节点并向其返回 boost::shared_ptr()。

查看 libstdc++ 代码,我发现我正在调用的 std::allocator 函数如下所示:

分配器使用in-placement new来分离内存的分配和对象的构造。因此,可以获取大量元素并在真正需要对象时仅调用构造函数。

create_node函数使用分配器概念创建单个对象,并在需要时使用 shared_ptr 调用析构函数。为了使这些单一分配便宜,我想稍后替换分配器(因此我想要一个使用池分配的分配器)。

当我调用此函数时,它将在堆栈上创建一个临时实例,然后将节点的元素复制到堆位置。如何强制编译器立即就地创建对象?因此,我想要一个倒置的命名返回值优化 (NRVO)。这可能吗?

0 投票
6 回答
16501 浏览

c++ - 基于堆栈缓冲区的 STL 分配器?

我想知道是否有一个符合 C++ 标准的库是否可行,该库allocator使用位于堆栈上的(固定大小的)缓冲区。

不知何故,这个问题似乎还没有在 SO 上以这种方式提出,尽管它可能已经在其他地方得到了隐含的回答。

所以基本上,就我的搜索而言,似乎应该可以创建一个使用固定大小缓冲区的分配器。现在,乍一看,这应该意味着也应该一个分配器,它使用一个“存在”在堆栈上的固定大小的缓冲区,但它确实出现了,周围没有广泛的这种实现。

让我举一个例子来说明我的意思:

这将如何实现?


这个其他问题的答案(感谢 R. Martinho Fernandes)链接到来自铬源的基于堆栈的分配器:http: //src.chromium.org/viewvc/chrome/trunk/src/base/stack_container.h

然而,这个类似乎非常奇特,特别是因为StackAllocator 它没有默认的 ctor——而且我认为每个分配器类都需要一个默认的 ctor

0 投票
3 回答
3695 浏览

c++ - Converting between vectors with different allocators

I have written a simple C++11 style stateful allocator type. Given

What is the best way to allow conversions from a my_vector to a std::vector using the default allocator? GCC 4.7 (recent svn) says

error: conversion from 'my_vector<int> {aka std::vector<int, my_allocator<int>>}' to non-scalar type 'std::vector<int>' requested

Obviously this could be done with, say, a simple conversion function such as

but this seems pretty inelegant. Is there a better solution in C++11?

Move semantics are right out in this situation, of course, but I'd like copy construction and assignment to work without extra noise/typing.

0 投票
8 回答
33887 浏览

c++ - 向量的数据如何对齐?

如果我想std::vector用 SSE 处理数据,我需要 16 字节对齐。我怎样才能做到这一点?我需要编写自己的分配器吗?或者默认分配器是否已经与 16 字节边界对齐?

0 投票
1 回答
331 浏览

c++ - C++ 为基元调用 allocator.construct

我是否有必要为使用任意分配器分配的原始类型数组调用 allocator.construct(),如下面的代码清单所示?该类不需要将分配的内存初始化为任何特定值,因此在我看来,使用新分配的内存块调用 allocator.construct() 是不必要的。考虑到数组总是由原始类型组成,不调用这个方法有什么危险吗?

0 投票
2 回答
1022 浏览

c++ - std::string 分配策略

我对一些基本的字符串实现有点困惑。我一直在通过源代码了解内部工作并学习新事物。我无法完全掌握内存是如何管理的。

只是一些基本字符串实现的花絮

  • 原始分配器用于 char 类型

    /li>
  • ...然后当分配 Rep 被放置在分配的缓冲区__size中时,计算也适合字符

    /li>
  • 这是从 _Rep 缓冲区中获取字符数据的方式

    /li>
  • 设置角色 - 一种方式

    /li>

困扰我的是原始分配器是 char 类型,但分配的内存可能包含一个 _Rep 对象,加上字符数据(不一定是 char 类型)

此外,为什么(或者更确切地说如何)调用_M_refdata知道字符数据的开始(或结束)在缓冲区内的位置(即this+1

编辑:是否this+1只是将内部指针推到_Rep对象之后的下一个位置?

我对内存对齐和强制转换有基本的了解,但这似乎超出了我所读过的任何内容。

任何人都可以提供帮助,或者向我指出更多信息丰富的阅读材料吗?

0 投票
6 回答
1875 浏览

c++ - C++ 中的高效数组重新分配

我将如何有效地调整使用某些符合标准的 C++ 分配器分配的数组的大小?我知道 C++ 分配器接口中没有提供重新分配的工具,但是 C++11 修订版是否使我们能够更轻松地使用它们?假设我有一个定义vec了复制赋值运算符的类foo& operator=(const foo& x)。如果x.size() > this->size(),我被迫

  1. 对内部存储中的所有元素调用 allocator.destroy() foo
  2. 在内部存储上调用 allocator.deallocate()foo.
  3. 重新分配一个有足够空间容纳x.size()元素的新缓冲区。
  4. 使用 std::uninitialized_copy 填充存储。

有没有什么方法可以让我更轻松地重新分配内部存储foo而不必经历所有这些?如果您认为它有用,我可以提供一个实际的代码示例,但我觉得这里没有必要。