簡體   English   中英

使用 malloc 時 Valgrind “大小為 n 的無效寫入”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM