C关于指针内存分配的困惑?

C关于指针内存分配的困惑?,c,pointers,memory-management,C,Pointers,Memory Management,我很抱歉,如果这可能被视为一个重复,但我似乎无法找到一个决定性的答案,满足我的问题。 所以我有一个结构,它有一个指向指针的自引用指针 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 *pt

我很抱歉,如果这可能被视为一个重复,但我似乎无法找到一个决定性的答案,满足我的问题。 所以我有一个结构,它有一个指向指针的自引用指针

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->edges存储此指针。我很有信心我的分配是正确的(尽管效率很低),但这让我有点走神。。。所以,当人们声明指向指针的指针(例如,**ptr),然后为ptr和*ptr分配内存时,从技术上讲,这难道不会使ptr成为指向指向指针的指针(并且可能更清楚地声明为***ptr)?或者也许我错了,在概念上遗漏了什么


提前谢谢你

这取决于具体情况,没有一般的答案。如果您有一个指向指针的指针,例如
节点**
,并且希望将新数据存储到其中,那么您需要有两个级别的分配,否则一个就足够了

struct Node** nodes = calloc(AMOUNT, sizeof(struct Node*));
现在您有了一个
struct Node*
元素数组,因此每个元素都是指向
struct节点的指针

现在如何填充这个数组?您可能希望在其中插入新节点。那么你就需要分配它们了

nodes[0] = calloc(1, sizeof(struct Node)); // <- mind Node, not Node*
但是如果你有
s_图
,你已经分配了它们,所以它就像:

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      | 

你所拥有的在我看来还不错。除了在每个新节点上重新定位有点低效之外。通常的做法是分块分配/增长。“所以当人们声明指针指向指针(例如,**ptr),然后为ptr和*ptr分配内存时,”。你也这样做了。除了你的第二级(
*ptr
)不是动态内存,而是静态内存。
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      |