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 |