繁体   English   中英

如何在C中使用指针创建池?

[英]How can I make a pool with pointers in C?

我正在制作我的库,正当我想了解指针语法时,我很困惑,在网上搜索甚至变得更加困惑。

基本上我想做一个游泳池,这实际上是我想要做的:

语境

必须注意以下几点:

  • 当我将一个对象添加到池中时,当前对象数组的指针将添加到新的指针数组+ 1(以包含新对象)中。
  • 新数组由我的foo结构的“对象”指向。
  • 旧的数组是自由的。
  • 当我调用cleanup函数时,池中的所有对象均已释放

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

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 * 这种类型非常强大,因为它允许您将任何类型的指针放入池中。 但是,由您决定从池中检索void *指针时进行正确的强制转换。

你的结构看起来像这样

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

如中所示,是一个指针数组。

您的malloc:

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

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

另外,不必在每次向池中添加内容时分配新的指针,而只需使用reallochttp://www.cplusplus.com/reference/cstdlib/realloc/

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

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

首先,您已经回答了“ 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是将旧项目复制到新空间以及将新项目复制到新空间的更方便的方法。

void *引用void *是违反约束的,就像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。 看一下如何new_pointers = malloc(sizeof(???)*the_pool->n);new_pointers = malloc(sizeof(???)*the_pool->n); ...是什么让您认为需要一次循环(在myc_pool_cleanup中)来释放每个项目,而您可以一次犯规地释放它们呢?

可以使用realloc,但是否则您似乎可以在myc_push_in_pool *中完美地处理malloc / memcpy / free。 编写重新分配代码时,很多人会陷入困境。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM