草庐IT

c++ - 在具有预分配 block 的自定义 STL 分配器中重新绑定(bind)

coder 2023-06-02 原文

我要构建一个自定义分配器,预分配一个大块(数组)来存储N某些类的元素T ,然后在数组内增加一个索引来服务分配请求。

由于我想要对预分配 block 中的元素进行任何初始化,所以这样的事情不会起作用:

T buffer[N];

因为在这种情况下 T的构造函数将被调用 N block 的元素。

因为我的理解是 std::aligned_storage不打电话 T的构造函数,我想到了使用std::aligned_storage ,类似这样:

std::aligned_storage<
    N * sizeof(T),
    std::alignment_of<T>::value 
>::type buffer;

T* base = static_cast<T*>( static_cast<void*>(&buffer) );

然后分配器可以在请求分配 T 时增加基指针(直到 (base+N) ),并且 T 可以在 就地构造 (位置为 new )需要。

我想使用这个方案来定义一个用于 STL 容器的自定义分配器。但是,在我看来,重新绑定(bind)可能存在问题。事实上,如果我的理解是正确的,STL 分配器应该支持从类型 T 重新绑定(bind)。到类型 U ,例如因为像 std::list<T> 这样的容器(或其他基于节点的容器,如 std::map )使用分配器来分配实际上不是 T 类型的 节点 , 但类型不同 U (包含 T 和节点的其他“ header ”开销信息)。 那么,前面提到的 std::aligned_storage方法适用于重新绑定(bind)?或者(我认为)T 的正确对齐方式s 确实暗示另一个不同类型的正确对齐U ?

如何解决这个问题?

我如何定义前面提到的 buffer使其也适用于重新绑定(bind)到某些不同的类型 U ?

是否应该从不同的角度来解决这个问题?如果有,是什么?

最佳答案

你在正确的轨道上。

一个恼人的细节是分配器的拷贝必须比较相等,甚至转换(反弹)拷贝。比较相等意味着它们可以释放彼此的指针。所以像 std::list<int> 这样的容器将重新绑定(bind)your_alloc<int>your_alloc<node<int>>然后构造一个 your_alloc<node<int>>使用 your_alloc<int> .从技术上讲,您的your_alloc<node<int>>必须释放 your_alloc<int> 分配的指针.

Here是我试图满足这个要求。随意复制/修改/滥用此代码。我的目的是教育,而不是成为世界上的分配器供应商(无论如何这不会是有利可图的 :-))。

这个例子采用了一种稍微不同的对齐方式:我碰巧知道在我感兴趣的平台(OS X、iOS)上,malloc返回 16 字节对齐的内存,这就是我的自定义分配器需要返回的所有内容。您可以将该数字更改为适合您系统的任何数字。

这种对齐的硬连线意味着单个池可以安全地提供多个 allocator<int>allocator<node<int>> ,因为它们都是 16 字节对齐的(这就足够了)。这也意味着拷贝,甚至是转换后的拷贝,都可以检测指针何时指向缓冲区,因为所有拷贝都共享同一个缓冲区。

稍微不同的是,C++ 委员会已经有效地指定分配器是引用类型:拷贝是等价的并且指向同一个内存池。

您可以使用实际嵌入分配器中的内存池来逃避作弊,但只能在某些实现中使用一些容器,并且您不能引用标准来支持这一点。

关于c++ - 在具有预分配 block 的自定义 STL 分配器中重新绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15488527/

有关c++ - 在具有预分配 block 的自定义 STL 分配器中重新绑定(bind)的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. ruby - ruby 中的 TOPLEVEL_BINDING 是什么? - 2

    它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput

  7. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  8. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

  9. ruby - 在匿名 block 中产生 - 2

    我没有理解以下行为(另请参阅inthisSOthread):defdef_testputs'def_test.in'yieldifblock_given?puts'def_test.out'enddef_testdoputs'def_testok'endblock_test=procdo|&block|puts'block_test.in'block.callifblockputs'block_test.out'endblock_test.calldoputs'block_test'endproc_test=procdoputs'proc_test.in'yieldifblock_gi

  10. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

随机推荐