[英]Valgrind "Invalid write of size n" when using malloc
我正在使用這種結構創建一個圖表
struct node
{
int id;
struct node *ad;
};
struct graph
{
int numVert;
struct node **adjList;
int *visited;
int *back;
};
並使用它來分配內存
static struct graph *graph_create(struct world *W, int v)
{
struct graph *G = NULL;
if ((G = graph_alloc(v)) != NULL)
{
/* some stuff */
}
return G;
}
static struct graph *graph_alloc(int v)
{
struct graph *G = NULL;
int i;
struct node **newNode = NULL;
if ((G = (struct graph *)malloc(sizeof(struct graph *))) != NULL)
{
G->numVert = v;
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
}
/* other stuff */
return G;
}
但是當我使用-s --leak-check=full --show-leak-kinds=all
編譯時,valgrind 向我展示了這個,我不知道為什么
==65390== Invalid write of size 8
==65390== at 0x10985D: graph_alloc (main.c:299)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
==65390== Address 0x4a429c8 is 0 bytes after a block of size 8 alloc'd
==65390== at 0x483F7B5: malloc (vg_replace_malloc.c:381)
==65390== by 0x109830: graph_alloc (main.c:296)
==65390== by 0x109801: graph_create (main.c:283)
==65390== by 0x10925F: main (main.c:75)
我認為問題在於那一行因為沒有它就沒有錯誤
G->adjList = (struct node **)malloc(v * sizeof(struct node *));
當您嘗試在此處為圖形結構分配內存時:
struct graph *G = NULL;
G = (struct graph *) malloc(sizeof(struct graph *));
您僅為指向結構的指針分配內存,但您需要為指針指向的事物分配內存:
struct graph *G = malloc(sizeof(*G));
您還可以指定類型的大小:
struct graph *G = malloc(sizeof(struct graph));
但我喜歡成語Type *p = malloc(sizeof(*p))
。 您從malloc
獲得的指針是您分配的給定大小的內存的句柄。 重要的不是指針p
的大小,而是它指向的大小,即*p
。
在您的情況下,圖形結構由三個指針和一個整數組成,因此圖形結構比指向圖形結構的指針需要更多的內存。 這就是導致無效寫入的原因。
兩個觀察:
在 C 中,不需要強制轉換為(struct graph *)
,因為void *
可以轉換為指向其他對象的指針。
我發現在if
子句中同時執行賦值和空值檢查會使代碼混亂,並且很難看到發生了什么。 代替
struct graph *G = NULL; if ((G = malloc(sizeof(*G))) != NULL) ...
我更喜歡:
struct graph *G = malloc(sizeof(*G)); if (G != NULL) ...
它將內存分配與成功測試分開。 它也有更少的括號。 :)
(這可能是個人喜好問題,但我的印象是初學者非常喜歡這些復雜的結構。保持簡單。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.