English 中文(简体)
ice/car/par/把单一小块混入具有不同类型/种类的多阵种的方法?
原标题:Canonical way to dice/carve/parcel a single malloc into multiple arrays with varying types/alignments?

www.un.org/Depts/DGACM/index_spanish.htm 我有99种例行公事,需要临时储存各种不同的数据类型,并满足不同的统一要求。 目前,我打电话<条码>>,多度使用(a) 介绍大量间接费用和(b) ,并不能保证我的士们有良好的记忆。 我不能把温室装成单一结构,因为规模要求只是常年才知道。

。 我要说的是<条码>小型(或类似)一度,其规模足够大,我可以 d上/car上/把个别点人与所需调整联系起来。 在C99中是否具备了完成这项任务的 can?

A possible (but unlikely) answer for a concrete example: Say I want to allocate enough space for a char[3], a double[m] with 16-byte alignment, an int, and a float[n] with 16-byte alignment and that I require them in memory in that order. Please ignore that the order is stupid and the example contrived. My actual use case is a a control struct followed by several temporary arrays of mixed integer/numeric types with alignments allowing SSE operations.

利用。 如何只使用标准图书馆来分配一致的记忆? 可以:

// Several unnecessary values (e.g. alignment_c) are holdovers
// from the macros generating this logic.

// ell, m, and n are sizes known only at runtime

const size_t    datasize_c  = 3*sizeof(char);
const size_t    alignment_c = __alignof__(char);
const size_t    pad_c       = alignment_c - 1;
const uintptr_t mask_c      = ~(uintptr_t)(alignment_c - 1);

const size_t    datasize_d  = ell*sizeof(double);
const size_t    alignment_d = __alignof__(double) > 16 ? __alignof__(double) : 16;
const size_t    pad_d       = alignment_d - 1;
const uintptr_t mask_d      = ~(uintptr_t)(alignment_d - 1);

const size_t    datasize_i  = m*sizeof(int);
const size_t    alignment_i = __alignof__(int);
const size_t    pad_i       = alignment_i - 1;
const uintptr_t mask_i      = ~(uintptr_t)(alignment_i - 1);

const size_t    datasize_f  = n*sizeof(float);
const size_t    alignment_f = __alignof__(float) > 16 ? __alignof__(float) : 16;
const size_t    pad_f       = alignment_f - 1;
const uintptr_t mask_f      = ~(uintptr_t)(alignment_f - 1);


const size_t p_parcel = (datasize_c + pad_c)
                      + (datasize_d + pad_d)
                      + (datasize_i + pad_i)
                      + (datasize_f + pad_f) ;

void   * const p = malloc(p_parcel) ;
char   *       c = (void *) (((uintptr_t)(p      ) + pad_c & mask_c));
double *       d = (void *) (((uintptr_t)(c + ell) + pad_d & mask_d));
int    *       i = (void *) (((uintptr_t)(d + m  ) + pad_i & mask_i));
float  *       f = (void *) (((uintptr_t)(i + n  ) + pad_f & mask_f));

// check if p is NULL, use (c, d, i, f), then free p

我认为,这种可能性在功能上是正确的,但我不禁要问,是否有更好、更清洁、更短的途径?

我认为,使用浮舱的方法是行不通的,因为我只能保证使用单一构造的小型水体对一个阵列进行统一。 我仍然需要三个<代码>。 要求有三处不同的障碍。

最后,我很高兴能够提供如果任何人想要的话,会产生这些东西的宏观。

最佳回答
struct malloc_wrapper {
    char *storage;
    size_t capacity;
    size_t first_free;
};

initialise it:

void init_malloc_wrapper(struct malloc_wrapper *mw, size_t cap) { // or int
    if (!mw) {
        perror("No struct malloc_wrapper passed
");
        exit(EXIT_FAILURE);
    }
    mw->storage = malloc(cap);
    if (mw->storage == NULL) {
        perror("allocation failed
");
        exit(EXIT_FAILURE); // or return 0;
    }
    mw->capacity = cap;
    mw->first_free = 0;
    // return 1;
}

void clear_malloc_wrapper(struct malloc_wrapper *mw) {
    if (!mw) {
        return;
    }
    if (mw->storage) {
        free(mw->storage);
    }
    mw->storage = NULL;
    mw->capacity = 0;
    mw->first_free = 0;
}

a. 支付记忆库:

// First version assumed that `malloc` returns memory aligned suitable for all requests.
// That s probably true, but just in case, we have to be a bit more cautious.
void *deal_out(struct malloc_wrapper *mw, size_t align, size_t size, size_t nmemb) {
    if (!align || (align & (align-1))) {
        perror("invalid alignment
");
        exit(EXIT_FAILURE);
    }
    if (!mw) {
       perror("No malloc_wrapper
");
        exit(EXIT_FAILURE);
    }
    uintptr_t start = ((uintptr_t(mw->storage) + mw->first_free + align-1) & ~(align-1);
    size_t offset = start - (uintptr_t)mw->storage;
    if ((mw->capacity - offset) < size*nmemb) {
        return NULL;   // not enough space
    }
    mw->first_free = offset + size*nmemb;
    return (void *)start;
}

视亚底,可能需要进行更多的检查。 你们可以在必要时处理适当配对的空白。 但是,如果你没有在初始化时分配足够的储存,那么处理进一步的请求就有些复杂。 释放是完全或根本没有。 因此,这不是一个改进。

<><>Edit>: 为了处理初步能力问题,可以增加一个储存库清单,仅供点人使用,或储存、抵消和剩余能力。 如果新申请超过现有能力,则在清单中增加现有储存库,并分配新的储存库。 如果能够记住旧的棚户的剩余能力,人们可以要求小户人填写旧丘,看看它是否适合其中之一。

第一个版本的<代码>deal_out <>/code>对统一要求的可能性作了说明,比现在确定的<代码>小型>回归要求更加一致。

问题回答

暂无回答




相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签