我正在尝试实现需要这样结构的东西:
struct abc
{
int size;
struct abc *links[size];
}
在这里,我希望size
在运行时更改,而不仅仅是abc
的每个实例都不同,abc
的实例根据程序具有不同数量的链接。如何为这样的数据结构创建/管理/分配内存?甚至可以在C?
答案 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;
}