你如何表示一个指向多个对象的容器?

时间:2014-08-27 06:11:33

标签: c pointers

假设我们有以下内容:

struct main_container{
   struct sub_container* pointers;
}

struct object{
   char* name;
}

struct sub_container{
   //?
}

我的想法是,main_container pointers应该指向多个object,但我不确定要放入{{1} }}。我在想像sub_container这样的东西,但似乎我必须为此分配新的内存,当我想要做的只是指向已经存在于内存中的多个对象时。因此假设内存中存在10个struct object** o;object保存指向4个随机的指针或6个随机指针。有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:1)

需要指向对象的指针?然后只需添加它:

struct sub_container{
    struct object * ptr;
}

您可以将其指定为:

struct main_container mc;
mc.pointers = malloc(20 * sizeof(*mc.pointers)); // Remember to check in real code if malloc fails
struct object obj;
mc.pointers[0].ptr = &obj; // Assign external object to container

但是你需要sub_container吗?如果它只是持有一个指针,你可以摆脱它:

struct main_container{
    struct object** pointers;
}

...
mc.pointers[0] = &obj;

答案 1 :(得分:0)

你必须知道最大对象数量.. 否则你必须为指针分配空间..

#define MAX_OBJS (10)

struct sub_container
{
    struct object *obj[MAX_OBJS];
}

但我认为没有必要使用sub_container?!

答案 2 :(得分:0)

如前所述,如果要在运行时添加和删除更多对象,则必须动态地为指针分配空间。

object** objects = malloc(NUM_POINTERS_TO_STORE * sizeof(struct object*));

并且你可以通过

访问第n个指针
struct object* nth_object = objects[n];

只要n小于NUM_POINTERS_TO_STORE。

如果要在运行时经常修改容器,可能需要编写一些访问函数。我为一个类似矢量的容器写了一个简短的例子。

#include <stdlib.h>
#include <assert.h>

typedef struct
{
    char* name_;
    // other data
} object;

typedef struct
{
    object** objects_;
    int size_;
    int alloc_;
} object_container;

object_container* oc_create()
{
    object_container* oc = malloc(sizeof(object_container));
    if(!oc) return NULL;
    oc->size_ = 0;
    oc->alloc_ = 1; // use an initial size 
    oc->objects_ = malloc(oc->alloc_ * sizeof(object*));
    return oc;
}

void oc_destroy(object_container* oc)
{
    if(oc) free(oc);
}

void oc_append(object_container* oc, object* o)
{
    assert(oc);
    assert(oc->objects_);
    assert(oc->alloc_ > 0);

    // reallocate memory if not enough space
    if(oc->alloc_ <= oc->size_) {
        oc->alloc_ *= 2;
        oc->objects_ = realloc(oc->objects_, (oc->alloc_ * sizeof(object*)));
        // some error checking would be good here
    }
    // append object
    oc->objects_[oc->size_++] = o;
 }

 object* oc_getat(object_container* oc, int index)
 {
     if(oc && oc->size_ > index) {
          return oc->objects_[index];
     }
     return NULL;
 }

 int main(int argc, char* argv[])
 {
     object_container* oc = oc_create();

     object o0, o1, o2;
     oc_append(oc, &o1);
     oc_append(oc, &o2);
     oc_append(oc, &o0);

     object* o = oc_getat(oc, 0);
     assert(o == &o1);
     o = oc_getat(oc, 5);
     assert(o == NULL);

     oc_destroy(oc);

     return 0;
 }

它还没有完成,您可能想要添加更多功能,但我认为应该足以获得这个想法。