可变大小类的分配 [英] Allocation of variable-sized class

查看:224
本文介绍了可变大小类的分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可变长度的数据结构,多维迭代器:

  class Iterator 
{
public:
static迭代器& init(int dim,int * sizes,void * mem)
{
return *(new(mem)Iterator
}

static size_t alloc_size(int dim)
{
return sizeof(Iterator)+ sizeof(int)* 2 * dim;
}

void operator ++()
{
//递增计数器,更新pos_和done_
}

bool done ()const {return done_; }
bool pos()const {return pos_; }

private:
Iterator(int dim,int * sizes):dim_(dim),pos_(0),done_(false)
{
for int i = 0; i for(int i = 0; i }

int dim_;
int pos_;
bool done_;
int size(int i){return reinterpret_cast< int *>(this + 1)[i] }
int& counter(int i){return reinterpret_cast< int *>(this + 1)[dim_ + i]; }
};

迭代器的维数在编译时是未知的,但可能很小,所以我为迭代器与 alloca

  void * mem = alloca alloc_size(dim)); 

for(Iterator& i = Iterator :: create(dim,sizes,mem);!i.done(); ++ i)
{
// do something with i.pos()
}

迭代器?我知道一个事实,从函数返回,它的堆栈解开,因此 alloca 必须在调用者的堆栈帧中使用(参见例如这里)。此回答表明分配在默认参数中执行:

  static迭代器& init(int dim,int * sizes,void * mem = alloca(alloc_size(dim))); 

但是优雅,这个解决方案不能帮助我:默认参数引用参数' dim'。不幸的是,由于 dim

是一个运行时值,没有任何方法来做这个除了一个宏:

  #define CREATE_ITERATOR dim,sizes)\ 
Iterator :: init(dim,sizes,alloca(Iterator :: alloc_size(dim)))


I have a variable length data structure, a multi-dimensional iterator:

class Iterator
{
public:
    static Iterator& init(int dim, int* sizes, void* mem)
    {
        return *(new (mem) Iterator(dim, sizes));
    }

    static size_t alloc_size(int dim)
    {
        return sizeof(Iterator) + sizeof(int) * 2 * dim;
    }

    void operator++()
    {
        // increment counters, update pos_ and done_
    }

    bool done() const { return done_; }
    bool pos()  const { return pos_; }

private:
    Iterator(int dim, int* sizes) : dim_(dim), pos_(0), done_(false)
    {
        for (int i=0; i<dim_; ++i) size(i) = sizes[i];
        for (int i=0; i<dim_; ++i) counter(i) = 0;
    }

    int  dim_;
    int  pos_;
    bool done_;
    int  size   (int i) { return reinterpret_cast<int*>(this+1)[i]; }
    int& counter(int i) { return reinterpret_cast<int*>(this+1)[dim_+i]; }
};

The dimensionality of the iterator is not known at compile time but probably small, so I allocate memory for the iterator with alloca:

void* mem = alloca(Iterator::alloc_size(dim));

for (Iterator& i = Iterator::create(dim, sizes, mem); !i.done(); ++i)
{
    // do something with i.pos()
}

Is there a more elegant way of allocating memory for the iterator? I am aware of the fact that upon returning from a function, its stack is unwound, thus alloca must be used in the caller's stack frame (see e.g. here). This answer suggests that the allocation be performed in a default parameter:

static Iterator& init(int dim, int* sizes, void* mem = alloca(alloc_size(dim)));

However elegant, this solution does not help me: Default argument references parameter 'dim'. Any suggestion for a nice solution?

解决方案

Unfortunately, given that dim is a run-time value, there isn't any way to do this other than with a macro:

#define CREATE_ITERATOR(dim, sizes) \
    Iterator::init(dim, sizes, alloca(Iterator::alloc_size(dim)))

这篇关于可变大小类的分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆