簡體   English   中英

VALGRIND對大小8的無效讀取,鏈接列表,釋放節點

[英]VALGRIND invalid read of size 8, linked list, freeing nodes

我正在嘗試找出Valgrind抱怨的原因。

如果有人可以給我一個提示,以便我能理解為什么我的代碼會產生不良行為,我將不勝感激。

我創建了一個結構數組。 每個條目都是由結構組成的鏈表的開頭。 現在,我要釋放該結構數組的每個鏈接列表中的元素。

但是瓦爾格朗德說:

==15084== Memcheck, a memory error detector
==15084== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==15084== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==15084== Command: /tmp/3RKi4ZeFa74f-a.out tests/16_allPositive output/ausgabe_16_allPositive
==15084== 
==15084== Invalid read of size 8
==15084==    at 0x402006: reset (1441261801.c:807)
==15084==    by 0x402489: main (1441261801.c:927)
==15084==  Address 0x51e0de8 is 8 bytes inside a block of size 16 free'd
==15084==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==15084==    by 0x401FF5: reset (1441261801.c:809)
==15084==    by 0x402489: main (1441261801.c:927)
==15084== 
==15084== Invalid read of size 8
==15084==    at 0x401FEA: reset (1441261801.c:809)
==15084==    by 0x402489: main (1441261801.c:927)
==15084==  Address 0x51e0d48 is 8 bytes inside a block of size 16 free'd
==15084==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==15084==    by 0x401FF5: reset (1441261801.c:809)
==15084==    by 0x402489: main (1441261801.c:927)
==15084== 
==15084== Invalid read of size 8
==15084==    at 0x401FFA: reset (1441261801.c:807)
==15084==    by 0x402489: main (1441261801.c:927)
==15084==  Address 0x51e0d48 is 8 bytes inside a block of size 16 free'd
==15084==    at 0x4C29E90: free (vg_replace_malloc.c:473)
==15084==    by 0x401FF5: reset (1441261801.c:809)
==15084==    by 0x402489: main (1441261801.c:927)
==15084== 
==15084== 
==15084== HEAP SUMMARY:
==15084==     in use at exit: 0 bytes in 0 blocks
==15084==   total heap usage: 119 allocs, 119 frees, 7,787 bytes allocated
==15084== 
==15084== All heap blocks were freed -- no leaks are possible
==15084== 
==15084== For counts of detected and suppressed errors, rerun with: -v
==15084== ERROR SUMMARY: 51 errors from 3 contexts (suppressed: 0 from 0)

那似乎是錯誤的功能

    void reset()
 784: {
 785:   //lösche alle (zeiger)char *arrays der conti structs
 786:   for(int i = 0; i < zeile1; i++)
 787:   {
 788:   struct node *p = &conti[i];
 789:   if((*p).next != NULL)
 790:   {
 791:       for(; (*p).next != NULL; p=(*p).next)
 792:       {
 793:                   free((*p).volume);
 794:       }
 795:                   free((*p).volume);
 796:   }else if ((*p).next == NULL)
 797:   {
 798:                   free((*p).volume);
 799:       }
 800:   }
 801:   //lösche die listenelemente der jeweiligen container
 802:   for(int i = 0; i < zeile1; i++)
 803:   {
 804:   struct node *p = &conti[i];
 805:   if((*p).next != NULL)
 806:   {
 807:       for(; (*p).next != NULL; p=(*p).next)
 808:       {
 809:                   free((*p).next);
 810:       }
 811:   }
 812:   }
 813:   //lösche die (zeiger)input char *arrays
 814:   for (int j = 0; j < zeile2; j++)
 815:   {
 816:       free(input[j].volume);
 817:       }
 818:   //lösche die struct arrays
 819:       free(conti);
 820:       free(input);
 821: }

結構如下所示:

  16: struct node {
  17:   char *volume;
  18:   struct node *next;
  19:   };

我期待着您的幫助。

這是一種相當典型的編碼樣式,在(a)您使用valgrind或(b)實際上有一個系統中,另一個線程可以在釋放它后保留您的內存,該代碼風格才能起作用。

for(; (*p).next != NULL; p=(*p).next)
{
     free((*p).next);
}

當您經歷該循環時,您將擁有p,然后釋放其指向的對象。

free(p->next); //p->next now points to freed memory

然后,您掌握了剛剛釋放的東西

p = p->next; //p now points to freed memory

然后您就可以釋放指向的內容

free(p->next); //Trying to access freed memory

然后,您必須具有額外的代碼才能釋放列表中的第一個元素,因為您無法在該循環中釋放它。

請注意, 湯姆·坦納Tom Tanner )在回答中給出了正確的診斷 為此請給他功勞。

請使用->箭頭運算符代替(*p).next 它是有充分理由發明的。

您的釋放代碼當前為:

struct node *p = &conti[i];
if((*p).next != NULL)
{
    for(; (*p).next != NULL; p=(*p).next)
    {
        free((*p).next);
    }
}

請注意,循環重復在代碼的if條件下進行的測試; 這是不必要的,當然,您可以簡單地刪除if代碼,但不能刪除其中的循環。

該代碼應注意避免訪問釋放的內存。 您可以使用或多或少的標准技術來做到這一點,該技術會在內存釋放之前保留next指針值:

struct node *p = &conti[i]->next;
while (p != NULL)
{
    struct node *next = p->next;
    free(p);
    p = next;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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