问题描述
我想开发一个多线程C ++应用程序(最终大多数C ++代码将由应用程序本身生成,这可能被视为一种高级别领域特定的语言)在Linux / AMD64 / Debian与GCC 4.6(可能是最新的C ++ 11标准)。我真的想使用对我所有的堆分配,因为我想分配 new(GC)
,从不关心 delete
。我假设Boehm的GC工作得很好。
使用C ++(而不是C)的主要动机是所有的算法和集合 std :: map
... std :: vector
由C ++标准库提供。
Boehm的GC提供了一个 gc_allocator< T>
模板(在其文件gc / gc_allocator.h中)。
我应该重新定义 operator :: new
为Boehm的一个吗?
或者我应该使用所有的显式分配器模板参数设置为 gc_allocator
的集合模板?我不太清楚第二个模板参数(分配器)对?它是用来分配向量内部数据还是分配每个单独的元素?
而且 std :: string
-s?如何使他们的数据GC分配?我应该有自己的字符串,使用 basic_string
模板与 gc_allocator
?是否有一些方法可以获得 GC_malloc_atomic
不是 GC_malloc
?
$ b
或者你建议不要使用由g ++编译的应用程序使用Boehm GC吗?
注意。
要部分回答我自己的问题,下面的代码
// 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(){};
};
externCMyvec * myvec_make(size_t sz = 0){return new(GC)Myvec(sz); }
externCvoid myvec_resize(Myvec * vec,size_t sz){vec-> resize(sz); }
externCint myvec_get(Myvec * vec,size_t ix){return(* vec)[ix] 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
/ p>
因此,通过使用 gc_allocator
和 new(GC)
显然可以确定在我不知情的情况下不使用纯文本 :: opertor new
或 malloc
需要重新定义 :: operator new
I want to develop a multi-threaded C++ application (where eventually most of the C++ code would become generated by the application itself, which could be viewed as a high-level domain specific language) on Linux/AMD64/Debian with GCC 4.6 (and probably latest C++11 standard).
I really want to use Boehm's conservative garbage collector for all my heap allocations, because I want to allocate with new(GC)
and never bother about delete
. I am assuming that Boehm's GC is working well enough.
The main motivation for using C++ (instead of C) is all the algorithms and collections std::map
... std::vector
provided by the C++ standard library.
Boehm's GC provide a gc_allocator<T>
template (in its file gc/gc_allocator.h).
Should I redefine operator ::new
as Boehm's one?
Or should I use all the collection templates with an explicit allocator template argument set to some gc_allocator
? I don't understand exactly the role of the second template argument (the allocator) to std::vector? Is it used to allocate the vector internal data, or to allocate each individual element?
And what about std::string
-s? How to make their data GC-allocated? Should I have my own string, using basic_string
template with gc_allocator
? Is there some way to get the internal array-s of char allocated with GC_malloc_atomic
not GC_malloc
?
Or do you advise not using Boehm GC with an application compiled by g++ ?
Regards.
To answer partly my own question, the following code
// 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; }
when compiled with g++ -O3 -Wall -c myvec.cc
produces an object file with
% 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
So there is no plain malloc or ::operator new
in the generated code.
So by using gc_allocator
and new(GC)
I apparently can be sure that plain ::opertor new
or malloc
is not used without my knowledge, and I don't need to redefine ::operator new
这篇关于C ++标准库和Boehm垃圾收集器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!