[英]Unable to allocate pointers in C
我正在使用鄰接矩陣制作圖。
這是我的頭文件-graph.h-
typedef struct Node{
int vertex;
}Node_t;
typedef Node_t *Row;
typedef struct graph_t{
int noOfVertices;
Row *rowPointer;
}graph_t, *graph_p;
這是我的定義文件-graph.c-
graph_p createGraph(int noOfVertices){
int i,
j;
graph_p graph = (graph_p)malloc(sizeof(graph_t));
graph->noOfVertices = noOfVertices;
graph->rowPointer = (Row *)malloc(noOfVertices * sizeof(Row));
fprintf(stdout, "\nValue of graph->rowPointer: %p\n", graph->rowPointer);
for(i = 0; i < noOfVertices; i++){
Row r = (Node_t *)malloc(noOfVertices * sizeof(Node_t));
fprintf(stdout, "Value of r: %p\n", r);
graph->rowPointer[i] = &r;
fprintf(stdout, "Value of graph->rowPointer[%d]: %p\n", i, graph->rowPointer[i]);
}
for(i = 0; i < noOfVertices; i++){
for(j = 0; j < noOfVertices; j++){
Row* row = graph->rowPointer[i];
fprintf(stdout, "Value of row: %p\n", row);
row[j]->vertex = 0;
fprintf(stdout, "Value of row[%d]->vertex: %d\n", j, row[j]->vertex);
}
}
return graph;
}
但是我的輸出是-
graph-> rowPointer的值:003E3C50
r的值:003E3C70 graph-> rowPointer [0]的值:0028FEDC
r的值:003E3C90
graph-> rowPointer [1]的值:0028FEDC
r的值:003E3CB0
graph-> rowPointer [2]的值:0028FEDC
r的值:003E3CD0
graph-> rowPointer [3]的值:0028FEDC
r的值:003E3CF0
graph-> rowPointer [4]的值:0028FEDC
行值:0028FEDC
row [0]-> vertex的值:0
行值:0028FEDC
row [1]-> vertex的值:0
行值:0028FEDC
row [2]-> vertex的值:0
行值:0028FEDC
然后代碼進入無限循環。
因此,當我分配graph->rowPointer[i] = &r;
時似乎存在問題graph->rowPointer[i] = &r;
, 為什么是這樣? 我認為我已經正確分配了指針。 有人可以告訴我怎么了嗎? 謝謝!
你以為是對的
graph->rowPointer[i] = &r;
有問題。 您正在(並保留)自動變量的地址。 退出塊后,變量將超出范圍,而使指針懸空。
在我看來, rowPointer
的指針級別rowPointer
。 一個就足夠了。
r
是局部變量, &r
是其地址。 r
是一個指針,但&r
是一個不同的指針: &r
點r
而不是什么r
點。
您已經成功分配了r
指向動態分配的內存; 要使用它,只需將= &r
更改為= r
。
代碼中的r
是指向Node
的指針,該Node
在稱為堆的內存段中動態分配。 堆段包含您通過malloc-family為其分配空間的所有數據。 該段中的數據是持久性的,這就是為什么您需要自己使用free(void *)
釋放它。
請注意, r
指向 heap
段中數據所在的某處。 r
變量本身在堆棧段中,該段包含您聲明的所有常用變量,例如i
和j
。 由於r
變量是在for
循環內聲明的,因此其作用域僅限於該循環 。 這意味着&r
將指向堆棧中r
變量所在的某個位置,但是r
將在循環結束時被刪除。 您不能使用&r
因為r
不會存在於循環之外。
您無需在此處使用Node_t **
。 您可以只存儲分配的內存的地址,然后在for循環中獲取該地址作為指針,然后照常使用它。 也許是typedef Node_t *Row;
沒有幫助,您不應該將它們用於此類事情。 正如NPE指出的那樣,您有太多的指針級別。
您的.h應該如下所示:
struct node_t{
int vertex;
};
struct graph_t{
int noOfVertices;
node_t *rowPointer;
};
您需要做一些小的改動,例如:
graph->rowPointer = (node_t *)malloc(noOfVertices * sizeof(node_t));
graph_p *graph = malloc(sizeof(graph_t));
現在,您必須使用node_t *
而不是Row
。 只需像這樣直接存儲地址:
node_t *r = malloc(noOfVertices * sizeof(node_t));
graph->rowPointer[i] = r;
只需重寫一些行即可使用node_t *
而不是node_t **
。
編輯:老實說,標題的其余部分確實很糟糕。 您不應該使用那么多的typedef。 而且結構也不應該以大寫字母開頭。 更改了.h。
編輯2:同樣,這里的node_t
結構是沒有意義的,因為它僅包含一個int
。 這是您要使用typedef
,因此,無需制作該結構,只需執行typedef int node;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.