我对c很新,所以如果我的步骤有误,请告诉我。假设我有以下内容:
struct graphNode{
int val;
graphNode* parent;
int succSize;
int succMaxSize;
graphNode* succ[1];
};
我将创建一个新节点:
graphNode *n;
n = malloc(sizeof(struct graphNode));
assert(n);
n->val = 1;
n->parent = NULL;
n->succSize = 0;
n->succMaxSize = 1;
然后,如果我想在节点中添加后继者
if (n->succSize == n->succMaxSize){
n->succ = realloc(n->succ, sizeof(graphNode*) * n->succMaxSize * 2);
n->succMaxSize *= 2;
}
n->succ[succSize] = n2; //n2 is of type graphNode*
succSize++;
这是对的吗?我是否需要为结构重新分配或者是否足够重新分配数组?我需要malloc作为初始数组吗?初始数组大小是否应包含在我的malloc调用n?
中答案 0 :(得分:7)
在C中定义“弹性”数组成员的常用方法是指定大小为0
或根本没有大小,例如:
struct foo {
int stuff;
bar theBars[]; // or theBars[0]
};
根据此定义,sizeof(struct foo)
将包含末尾数组以外的所有元素,您可以通过说malloc(sizeof(struct foo) + numberOfBars * sizeof(bar))
来分配正确的大小。
如果您需要重新分配它以更改bar
元素的数量,那么您将使用相同的公式(但使用新的numberOfBars
)。
要清楚,你不能只是realloc
结构的一部分。你必须realloc
整个事情。
答案 1 :(得分:1)
realloc(ptr,size)
需要2个参数,而不是realloc(sizeof(graphNode*) * n->succMaxSize * 2)
// Something like ...
graphNode *n;
n->succSize = 0;
n->succMaxSize = 0; // set to 0
n->succ = NULL; // Initialize to NULL
// Then, if OP wants to add a successor to the node
if (n->succSize <= n->succMaxSize){
n->succ = realloc(n->succ, sizeof(graphNode*) * n->succMaxSize * 2);
n->succMaxSize *= 2;
}
n->succ[succSize++] = n2;
与所有内存分配一样,检查NULL
返回。在realloc()
中,应保存原始值,因此如果realloc()
失败,则原始指针不会丢失。
答案 2 :(得分:1)
通常当你看到struct definition时,最后一个字段是一个大小为0或1的数组,这意味着当结构被malloced时,作者将使用malloc做一些微妙的事情。
例如
struct foo {
int x;
:
:
type a[0];
};
使用类似
的malloc struct foo *p = malloc(sizeof(*p) + (n * sizeof(type));
这样做是为结构和尾随数组分配一块连续的内存。在这种情况下,数组大小为n。因此,在这种情况下对数组的引用是:
p->a[i] // where i >= 0 and i < n
这样做的一个原因是节省内存。
我确信在StackOver上有更好的解释;这是一个非常常见的C语言。
当数组是动态的时,通常不使用它。而是在malloc()时知道数组大小时使用它。当然,您可以动态使用,但必须重新分配整个内存块,而不仅仅是结构或数组。要将大小增加到2n,您可以说
p = realloc(p, sizeof(*p) + (2 * n * sizeof(type)));
现在你的数组是两倍大,它仍然是一块内存。
答案 3 :(得分:0)
如果你只想要一个数组,只需使succ
成为一个指针,只使用malloc / realloc等来为数组分配内存。
graphNode* succ;
你所做的几乎肯定要打破。
答案 4 :(得分:0)
我也是C的新手,但有些东西我可以直接看到。首先,您无法重新分配数组。在c89中,它们是编译时固定大小的。在C99和C11中,它们可以动态分配,但不能重新分配(据我所知)。所以为此,你需要分配一个
graphnode *succ;
指针和malloc(nodes * sizeof(node))。
graphNode* succ[1];
这会创建一个大小为1的数组,而不是一个最大索引为1的数组。因此,它与
的功能相同(几乎)graphNode* succ;
除了你做完之后你不能改变它的大小。
我认为你想要的是制作一棵树,具有动态可重新分配的分支数量。在这种情况下,您只需要重新分配graphNode *指针的大小,然后像索引一样通过索引访问每个元素。