为了账号安全,请及时绑定邮箱和手机立即绑定

C ++标准库和Boehm垃圾收集器

/ 猿问

C ++标准库和Boehm垃圾收集器

慕姐829404 2019-12-06 15:06:52

我想在Linux / AMD64 / Debian和GCC 4.6上开发一个多线程C ++应用程序(最终大多数C ++代码将由应用程序本身生成,可以将其视为高级领域特定语言)。可能是最新的C ++ 11标准)。


我真的想对我的所有堆分配使用Boehm的保守垃圾收集器,因为我想分配new(GC)而不用担心delete。我假设Boehm的GC运行良好。


使用(而不是C)C ++的主要动机是所有的算法和集合std::map... std::vector由C ++标准库提供。


Boehm的GC提供了一个gc_allocator<T>模板(在其文件gc / gc_allocator.h中)。


我应该重新定义operator ::new为Boehm的成员吗?


还是应该将所有收集模板与显式分配器模板参数设置为some一起使用gc_allocator?我不完全了解std :: vector的第二个模板参数(分配器)的作用?它是用于分配矢量内部数据,还是用于分配每个单独的元素?


那std::string-s呢?如何使他们的数据GC分配?我应该使用带basic_string模板的字符串gc_allocator吗?有什么方法可以让char的内部数组分配为GC_malloc_atomicnot GC_malloc?


还是建议不要将Boehm GC与g ++编译的应用程序一起使用?


问候。


查看完整描述

3 回答

?
森栏

为了部分回答我自己的问题,以下代码


// file myvec.cc

#include <gc/gc.h>

#include <gc/gc_cpp.h>

#include <gc/gc_allocator.h>

#include <vector>


class Myvec {

  std::vector<int,gc_allocator<int> > _vec;

public:

  Myvec(size_t sz=0) : _vec(sz) {};

  Myvec(const Myvec& v) : _vec(v._vec) {};

  const Myvec& operator=(const Myvec &rhs) 

    { if (this != &rhs) _vec = rhs._vec; return *this; };

  void resize (size_t sz=0) { _vec.resize(sz); };

  int& operator [] (size_t ix) { return _vec[ix];};

  const int& operator [] (size_t ix) const { return _vec[ix]; };

  ~Myvec () {};

};


extern "C" Myvec* myvec_make(size_t sz=0) { return new(GC) Myvec(sz); }

extern "C" void myvec_resize(Myvec*vec, size_t sz) { vec->resize(sz); }

extern "C" int myvec_get(Myvec*vec, size_t ix) { return (*vec)[ix]; }

extern "C" void myvec_put(Myvec*vec, size_t ix, int v) { (*vec)[ix] = v; }

使用编译时,g++ -O3 -Wall -c myvec.cc生成带有


 % nm -C myvec.o

                 U GC_free

                 U GC_malloc

                 U GC_malloc_atomic

                 U _Unwind_Resume

0000000000000000 W std::vector<int, gc_allocator<int> >::_M_fill_insert(__gnu_cxx::__normal_iterator<int*, std::vector<int, gc_allocator<int> > >, unsigned long, int const&)

                 U std::__throw_length_error(char const*)

                 U __gxx_personality_v0

                 U memmove

00000000000000b0 T myvec_get

0000000000000000 T myvec_make

00000000000000c0 T myvec_put

00000000000000d0 T myvec_resize

因此,没有普通的malloc或::operator new生成的代码中。


因此,通过使用gc_allocator和,new(GC)我显然可以确保在我不知情的情况下使用普通::opertor new或malloc不使用,并且不需要重新定义::operator new


供将来参考(感谢Sergey Zubkov在Quora中的评论中提到它),另请参见n2670和<memory>和垃圾回收支持(如std :: declare_reachable,std :: declare_no_pointers,std :: pointer_safety等)。但是,至少在当前的GCC或Clang中,尚未实现该功能(以琐碎但可以接受的使其成为无操作的方式除外)。


查看完整回答
反对 回复 2019-12-06
?
慕慕森

这完全取决于您对C ++的熟悉程度和熟练程度。您是否可以在不使用的情况下编写一个不错的C ++程序delete,您是否意识到new仅应在非常特殊的情况下使用它,并且在大多数情况下不需要指针?如果您了解所有这些并得出结论,您需要一个垃圾收集器,那么请务必继续。另一方面,如果您不这样做,您可能会发现惯用的现代C ++非常擅长于用户友好的确定性内存管理。

查看完整回答
反对 回复 2019-12-06
?
123456qqq

简而言之,根本没有理由new直接使用,也没有理由使用delete任何东西。从您的帖子来看,我给人留下的明显印象是,您完全不知道如何编写C ++代码,也不知道如何使用Standard提供的结构,而仅仅因为这是您习惯的范例而使用GC。

查看完整回答
反对 回复 2019-12-06

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信