简体   繁体   English

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

[英]C Confusion about pointer to pointers memory allocation?

I apologize if this might be viewed as a duplicate, but I cannot seem to find a conclusive answer that satisfies my question. 对于可能被视为重复的内容,我深表歉意,但是我似乎找不到一个能满足我的问题的结论性答案。 So I have a struct with a self referential pointer to pointers. 因此,我有一个带有指向指针的自引用指针的结构。

struct Node {
    int id;
    int edge_count;
    struct Node **edges;
}

static struct Node s_graph[MAX_ID+1];

I then have a function that allocates some memory. 然后,我有一个分配一些内存的函数。

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;
}

The above seems to work just fine. 以上似乎工作正常。 However, I keep seeing posts about pointer to pointers that lead me to wonder if I need to do something like the following in add_edge: 但是,我一直看到有关指针的帖子,这使我想知道是否需要在add_edge中执行以下操作:

struct Node *phead = malloc(sizeof(struct Node *));

However, this does not seem logical. 但是,这似乎不合逻辑。 There should be enough memory for ptail->edges to store this pointer after the realloc call. 在realloc调用之后,应该有足够的内存用于ptail-> edges存储此指针。 I am fairly confident that I did the allocation correctly (albeit, inefficiently), but it is kind of sending me on a mind trip ... So when people declare pointer to pointers (eg, **ptr) and then allocate memory for both ptr and *ptr, wouldn't that technically make ptr a pointer to pointers to pointers (and maybe clearer to declare as ***ptr)? 我相当有信心我正确地进行了分配(尽管效率很低),但这有点使我发狂……因此,当人们声明指针的指针(例如** ptr),然后为两者分配内存时ptr和* ptr,从技术上讲,这不会使ptr成为指向指针的指针的指针(也许更清楚地声明为*** ptr)吗? Or maybe I am wrong and missing something conceptually? 或者,也许我错了,在概念上缺少某些东西?

Thank you in advance! 先感谢您!

It depends on the situation, there is no general answer. 这取决于情况,没有普遍的答案。 If you have a pointer to pointer, eg Node** , and you want to store new data into it, then you need to have two levels of allocations, otherwise one is enough. 如果您有一个指向指针的指针,例如Node** ,并且想要将新数据存储到其中,则需要具有两个分配级别,否则一个分配就足够了。

struct Node** nodes = calloc(AMOUNT, sizeof(struct Node*));

Now you have an array of struct Node* elements, so each element is a pointer to a struct Node . 现在,您有了一个struct Node*元素数组,因此每个元素都是一个指向struct Node的指针。

Now how do you fill this array? 现在,您如何填充此数组? You could want to insert new nodes inside it. 您可能想在其中插入新节点。 Then you wouold require to allocate them, eg 然后您需要分配它们,例如

nodes[0] = calloc(1, sizeof(struct Node)); // <- mind Node, not Node*

But in your situation you just want to set the address to an element of an array of the static variable s_graph , so you don't need to allocate a second level, you directly set the value. 但是在您的情况下,您只想将地址设置为静态变量s_graph的数组的元素,因此您无需分配第二级,您可以直接设置该值。

So: 所以:

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    |

But if you have s_graph you already have them allocated, so it's something like: 但是,如果您有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      | 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM