如果这可能被视为重复,我道歉,但我似乎无法找到满足我的问题的结论性答案。 所以我有一个带有指向指针的自引用指针的结构。
struct Node {
int id;
int edge_count;
struct Node **edges;
}
static struct Node s_graph[MAX_ID+1];
然后我有一个分配一些内存的函数。
int add_edge(int tail, int head)
{
struct Node *ptail, *phead;
ptail = &s_graph[tail];
phead = &s_graph[head];
ptail->edges = realloc(ptail->edges, ++ptail->edge_count * sizeof(struct Node *));
if (ptail->edges) {
*(ptail->edges + ptail->edge_count - 1) = phead;
return 0;
}
return -1;
}
以上似乎工作得很好。但是,我一直看到关于指针指针的帖子让我想知道我是否需要在add_edge中执行以下操作:
struct Node *phead = malloc(sizeof(struct Node *));
然而,这似乎不符合逻辑。在realloc调用之后,应该有足够的内存用于ptail-gt; edge存储该指针。我相当确信我正确地进行了分配(尽管效率低下),但它有点让我精神错乱......所以当人们声明指针指针(例如** ptr)然后为两者分配内存时ptr和* ptr,技术上不会让ptr成为指向指针的指针(并且可能更清楚地声明为*** ptr)?或许我错了,在概念上遗漏了什么?
提前谢谢!
答案 0 :(得分:2)
这取决于具体情况,没有一般答案。如果你有一个指向指针的指针,例如Node**
,并且你想将新数据存储到指针中,那么你需要有两个级别的分配,否则就足够了。
struct Node** nodes = calloc(AMOUNT, sizeof(struct Node*));
现在您有一个struct Node*
元素数组,因此每个元素都是指向struct Node
的指针。
现在你如何填补这个阵列?您可能希望在其中插入新节点。然后你需要分配它们,例如
nodes[0] = calloc(1, sizeof(struct Node)); // <- mind Node, not Node*
但在您的情况下,您只想将地址设置为静态变量s_graph
数组的元素,因此您不需要分配第二级,直接设置该值。
所以:
struct Node** nodes = calloc(AMOUNT, sizeof(struct Node*));
nodes -> | 0 | 1 | 2 | 3 |
nodes[0] = calloc(1, sizeof(struct Node))
nodes -> | 0 | 1 | 2 | 3 |
|
|
v
| NODE |
但是如果你已经分配了s_graph
,那么它就像是:
static struct Node s_graph[MAX_ID+1];
struct Node** nodes = calloc(AMOUNT, sizeof(struct Node*));
nodes -> | 0 | 1 | 2 | 3 |
s_graph -> | N1 | N2 | N3 |
nodes[0] = &s_graph[0];
nodes -> | 0 | 1 | 2 | 3 |
|
|----|
v
s_graph -> | N1 | N2 | N3 |