struct中可变大小的self引用

时间:2011-12-21 20:48:35

标签: c struct

我正在尝试实现需要这样结构的东西:

struct abc
{  
  int size;
  struct abc *links[size];
}

在这里,我希望size在运行时更改,而不仅仅是abc的每个实例都不同,abc的实例根据程序具有不同数量的链接。如何为这样的数据结构创建/管理/分配内存?甚至可以在C?

5 个答案:

答案 0 :(得分:3)

最简单的方法是改变你的结构:

struct abc
{  
  int size;
  struct abc **links;
}

动态调用数组:

abc.links = (struct abc **)calloc(abc.size, sizeof(void *));

然后你可以这样解决链接数组的元素:

struct abc a,b,c, ...;
int n;
...
a.links = (struct abc **)calloc(a.size, sizeof(void *);
a.links[n] = &b;
struct abc *z = a.links[n];

小心不要尝试访问calloc'ed数组边界之外的元素,否则会出现内存异常和意外行为。还要记住为每个分配的结构释放(abc.links)以防止内存泄漏...

希望这有帮助

答案 1 :(得分:3)

C标准(C99及以下)预见了以下构造来处理这种情况,称为灵活数组成员:

struct abc
{  
  size_t size;
  struct abc *links[];
};

您将使用malloc分配这样的野兽:

struct abc * a = malloc(sizeof(struct abc) + sizeof(struct abc*[n]));
a.size = n;
for(size_t i = 0; i < n; ++i) a.links[i] = 0;
.
free(a);

答案 2 :(得分:1)

你可以做到这一点,但这不是自动的。我会用某种初始化程序来做这件事:

struct *abc abc_init(int size)
{
    struct abc *abc = calloc(1, sizeof(*abc));
    abc->size = size;
    abc->links = calloc(1, sizeof(*(abc->links)) * size);

    return abc;
}

然后你也可以有一个免费的例程:

void abc_free(struct abc *abc)
{
    for (int i = 0; i < abc->size; i++) {
        abc_free(abc->links[i]);
    }
    free(abc->links);
    free(abc);
}

请注意,abc_free()在此示例中为links中的每个元素调用自身,因此您必须在此处观看我们的递归。另请注意,此处缺少所有错误检查(例如NULL检查),以确保紧凑性。

这些例程简化了结构的创建和释放,然后您需要做的就是访问/设置它们。

答案 3 :(得分:0)

如果您不想记得致电free(abc.links)并且size在对象的生命周期内不会改变,则有可能:

struct abc
{  
    int size;
    struct abc *links[0]; // use 1 if your compiler complains
}

注意:这个特殊的零长度数组必须是结构的最后一个成员

你可能会问,零长度数组如何帮助?如果你用

分配abc,它就有效
 struct abc * a = malloc(sizeof(abc)+ size * sizeof(struct abc *));

这故意创造了太多的记忆,以便我们可以安全地使用a-&gt; links [3]或a-&gt; link [4](只要我们记得尊重size。我们可以然后只需使用free(a),我们就不需要(也不能)free(a->links);

在任何一种情况下,在尝试释放a->links[0]之前,请不要忘记将a->links[1]a->links[a->size - 1]中的每一个释放到a

答案 4 :(得分:0)

有人会写这个:

struct abc
{  
  size_t size;
  struct abc *links[1];
};

struct abc* abc_create(size_t size)
{
   struct abc* abc = calloc(1, sizeof(struct abc) + (size - 1) * sizeof(struct abc*));
   abc->size = size;
   return abc;
 }