2011-04-29 116 views
0
your program did not free all of the memory it allocated 
==17711== Memcheck, a memory error detector 
==17711== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
==17711== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info 
==17711== Command: ./counter 
==17711== 
==17711== Conditional jump or move depends on uninitialised value(s) 
==17711== at 0x400B98: main (counter.c:105) 
==17711== 
==17711== Conditional jump or move depends on uninitialised value(s) 
==17711== at 0x400BDB: main (counter.c:107) 
==17711== 
==17711== Conditional jump or move depends on uninitialised value(s) 
==17711== at 0x400C1B: main (counter.c:109) 
==17711== 
error 
==17711== 
==17711== HEAP SUMMARY: 
==17711==  in use at exit: 64 bytes in 4 blocks 
==17711== total heap usage: 4 allocs, 0 frees, 64 bytes allocated 
==17711== 
==17711== LEAK SUMMARY: 
==17711== definitely lost: 0 bytes in 0 blocks 
==17711== indirectly lost: 0 bytes in 0 blocks 
==17711==  possibly lost: 0 bytes in 0 blocks 
==17711== still reachable: 64 bytes in 4 blocks 
==17711==   suppressed: 0 bytes in 0 blocks 
==17711== Rerun with --leak-check=full to see details of leaked memory 
==17711== 
==17711== For counts of detected and suppressed errors, rerun with: -v 
==17711== Use --track-origins=yes to see where uninitialised values come from 
==17711== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 6 from 6) 
make: *** [test_counter] Error 1 

我在這個程序中的內存泄漏...我敢肯定,我已經無我所有的動態內存。我不明白的地方的泄漏= \C內存泄漏問題

#include "counter.h" 

/* ============================================================================ 
* File-global variables 
* ========================================================================== */ 
static int ncounters = 0; 
static struct counter *counters = NULL; 

static int nthreads = 0; 
static int *ninstructions = NULL; 
static struct instruction **instructions = NULL; 


/* ============================================================================ 
* Operations 
* ========================================================================== */ 
static void 
decrement(long long *n) { 
     (*n)--; 
} 

static void 
increment(long long *n) { 
    (*n)++; 
} 

static void 
mult2(long long *n) { 
    (*n)=(*n)*2; 
} 


/* ============================================================================ 
* Helper functions 
* ========================================================================== */ 

pthread_mutex_t lock1; 

/* ============================================================================ 
* Thread function 
* ========================================================================== */ 
static void * 
worker_thread(void *arg) { 

     pthread_mutex_lock(&lock1); 

     long long n = (long long)arg; 
     for(int i=0; i < ninstructions[n] ;i++){ 
      for(int j=0; j < instructions[n][i].repetitions ;j++){ 
      (*instructions[n][i].work_fn)(&((instructions[n][i].counter)->counter)); 
      } 
     } 
     pthread_mutex_unlock(&lock1); 
    return NULL; 
} 


/* ============================================================================ 
* Main function 
* ========================================================================== */ 
int 
main(void) { 

     scanf(" %d", &ncounters); //Ask for number of counters 

     int i; 

     if((counters = malloc(sizeof(struct counter)*ncounters))){ 
      for(i=0; i < ncounters ;i++){ 
      counters[i].counter = 0; 
      } 
     } 

     scanf(" %d", &nthreads); //Ask for number of threads 

     if((ninstructions = (int*) malloc(nthreads*sizeof(int)))){ 
      for(i=0; i < nthreads ;i++){ 
      ninstructions[i] = 0; 
      } 
     } 

     instructions = malloc(nthreads*sizeof(struct instruction *)); 

     for(i=0; i < nthreads ;i++){ 

      scanf(" %d", &ninstructions[i]); //Ask for number of instructions within threads[i] 

      instructions[i] = malloc(ninstructions[i]*sizeof(struct instruction)); 
      for(int j=0;j < ninstructions[i] ;j++){ 
      int Srepetition; 
      char Sfunction; 
      int Scounter; 

      scanf(" %d %c %d", &Scounter, &Sfunction, &Srepetition); 

      instructions[i][j].repetitions = Srepetition; 

      instructions[i][j].counter = (counters+Scounter); 

      if(Sfunction == 'I'){ 
       instructions[i][j].work_fn = increment; 
      }else if(Sfunction == 'D'){ 
       instructions[i][j].work_fn = decrement; 
      }else if(Sfunction == '2'){ 
       instructions[i][j].work_fn = mult2; 
      }else{ 
       printf("error\n"); 
      } 

      } 

     } 

     pthread_t thread_id[nthreads]; 

     for(long long i=0; i < nthreads ;i++){ 
      pthread_create(&thread_id[i], NULL, worker_thread, (void *)i); 
     } 

     for(int i=0; i < nthreads ;i++){ 
      pthread_join(thread_id[i], NULL); 
     } 

     for(i=0; i < ncounters ;i++){ 
      printf("%lld\n", counters[i].counter); 
     } 

     for(int i=0; i< nthreads;i++){ 
      free(instructions[i]); 
     } 
     free(instructions); 
     free(ninstructions); 
     free(counters); 
    return 0; 
} 
+2

請在此處添加所有相關代碼*。這是不合理的,期望人們按照鏈接來解決你在說什麼... – 2011-04-29 17:08:43

+0

所以我沒有得到我沒有免費仍然 – Jono 2011-04-29 17:57:24

+0

我建議你嘗試從你的代碼中刪除的東西,直到Valgrind報告變得乾淨。您刪除的最後一件事將是問題的原因。 – 2011-04-29 18:20:34

回答

5

你自由是instructions佔用的內存:

free(instructions); 

然後您訪問內存:

for(int i=0 ; i < nthreads ; i++){ 
    free(instructions[i]); 
} 

您在free(instructions)後無法訪問instructions

您需要首先釋放instructions中的指針,然後釋放instructions數組。

+2

注意將來,總是將釋放的指針的值設置爲NULL。那樣的話,如果你試圖釋放一些東西,或者在釋放一個指針後解引用,你會很容易地調試崩潰。 – nmichaels 2011-04-29 17:12:26

+0

我其實有循環免費說明[我]然後在我的代碼壽免費說明。 – Jono 2011-04-29 17:12:54

+0

@Jono:不,你不知道。你先釋放(指令),然後循環指令的內容。 – 2011-04-29 17:14:25

0

請向Valgrind添加選項--leak-check=full或者--show-reachable=yes,並將結果與​​當前源代碼一起發佈。當然,針對可執行文件的調試版運行Valgrind。

+0

它實際上是一個提供的自動測試案例,我不知道如何運行valgrind呢= \ – Jono 2011-04-29 17:24:55