0

我正在制作我的库,就在我想理解指针语法时,我只是感到困惑,在网上搜索并变得更加困惑。

基本上我想做一个游泳池,这就是我真正想做的事情:

语境

必须尊重以下几点:

  • 当我将一个对象添加到池中时,当前数组指向对象的指针被添加到一个新的指针数组 + 1(以包含新对象)。
  • 新数组由我的 foo 结构的“对象”指向。
  • 旧阵列正在释放。
  • 当我调用清理函数时,池中的所有对象都是空闲的

我应该如何定义我的结构?

typedef struct {
    int n;
    (???)objects
} foo;
foo *the_pool;

这是管理我的池的代码:

void myc_pool_init ()
{
    the_pool = (???)malloc(sizeof(???));
    the_pool->n = 0;
    the_pool->objects = NULL;
}

void myc_push_in_pool (void* object)
{
    if (object != NULL) {
        int i;
        (???)new_pointers;

        the_pool->n++;
        new_pointers = (???)malloc(sizeof(???)*the_pool->n);

        for (i = 0; i < the_pool->n - 1; ++i) {
            new_pointers[i] = (the_pool->objects)[i]; // that doesn't work (as I'm not sure how to handle it)
        }
        new_array[i] = object;

        free(the_pool->objects);
        the_pool->objects = new_array; // that must be wrong
    }
}

void myc_pool_cleanup ()
{
    int i;
    for (i = 0; i < the_pool->n; ++i)
        free((the_pool->objects)[i]); // as in myc_push_in_pool, it doesn't work
    free(the_pool->objects);
    free(the_pool);
}

注意:添加到池中的对象的类型事先不知道,所以我应该处理所有指针作为 void 任何反馈都会非常受欢迎。

4

2 回答 2

3

对您的问题的直接回答是:使用void *. 这种类型非常强大,因为它允许您在池中放置任何类型的指针。void *但是,在从池中检索指针时,由您执行正确的强制转换。

你的结构看起来像这样

typedef struct {
    int n;
    (void **)objects
} foo;
foo *the_pool;

如,一个指针数组。

你的malloc:

new_pointers = (void **)malloc(sizeof(void *)*the_pool->n);

这里有一个性能问题。您可以简单地分配一个固定大小的数组,并且只有在元素数量超过预定义的负载因子(= 使用的数量/最大大小)时才重新分配

realloc此外,您可以使用(http://www.cplusplus.com/reference/cstdlib/realloc/),而不是每次向池中添加内容时分配一个新指针

the_pool->objects = (void **)realloc(the_pool->objects, the_pool->n* sizeof(void*));

Realloc 尝试增加当前分配的区域,而不需要复制所有内容。只有当函数不能连续增加分配的区域时,它才会分配一个新的区域并复制所有内容。

于 2013-03-17T15:06:43.687 回答
0

首先,您已经回答了“foo.objects 的类型应该是什么?” 问题:void *objects;,malloc 已经返回void *。您的结构也需要存储size_t item_size;. n大概也应该是一个size_t

typedef struct {
    size_t item_count;
    size_t item_size;
    void *objects;
} foo;
foo *the_pool;

可以使用自制循环,但我认为 memcpy 是一种更方便的方式,可以将旧项目复制到新空间,并将新项目复制到新空间。

取消引用 avoid *是违反约束的,就像 a 上的指针算术一样void *,因此new_pointers需要是不同的类型。您需要一种指向正确大小的对象的类型。您可以使用正确数量的数组unsigned char,如下所示:

// new_pointers is a pointer to array of the_pool->item_size unsigned chars.
unsigned char (*new_pointers)[the_pool->item_size] = malloc(the_pool->item_count * sizeof *new_pointers);

// copy the old items
memcpy(new_pointers, the_pool->objects, the_pool->item_count * sizeof *new_pointers);

// copy the new items
memcpy(new_pointers + the_pool->item_count, object, sizeof *new_pointers);

请记住,free()只针对 malloc() 返回指针,并且应该是一一对应的:每个 malloc() 都应该是 free()d。看看你是如何 malloc 的:new_pointers = malloc(sizeof(???)*the_pool->n);......是什么让你认为你需要一个循环(在 myc_pool_cleanup 中)来释放每个项目,而你可以一口气释放它们?

可以使用 realloc,但您似乎可以完美地处理 malloc/memcpy/free *in myc_push_in_pool*。很多人在编写 realloc 代码时往往会搞砸。

于 2013-03-17T15:28:27.603 回答