Valgrind内存泄漏修复

时间:2015-05-21 19:36:25

标签: c memory-leaks valgrind

试图弄清楚如何解决我的内存泄漏问题。它说我在382块绝对损失中有726160个字节。我试图通过我的程序,发现它在我的malloc内存的行,但我无法弄清楚为什么。该行是:

   int ** pixels = (int **) malloc( *numCols * sizeof(int));

这是我的valgrind报告:

doe-MacBook:hw34 doe$ valgrind ./a.out -c 450 228 40 ./balloons.ascii.pgm balloon.pgm
==601== Memcheck, a memory error detector
==601== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==601== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==601== Command: ./a.out -c 450 228 40 ./balloons.ascii.pgm balloon.pgm
==601== 
==601== Invalid write of size 8
==601==    at 0x100000989: pgmRead (pgmUtility.c:28)
==601==    by 0x100001A79: main (main.c:112)
==601==  Address 0x100820e30 is 0 bytes after a block of size 2,560 alloc'd
==601==    at 0x1000076C1: malloc (vg_replace_malloc.c:303)
==601==    by 0x100000941: pgmRead (pgmUtility.c:26)
==601==    by 0x100001A79: main (main.c:112)
==601== 
==601== Invalid read of size 8
==601==    at 0x100000A01: pgmRead (pgmUtility.c:32)
==601==    by 0x100001A79: main (main.c:112)
==601==  Address 0x100820e30 is 0 bytes after a block of size 2,560 alloc'd
==601==    at 0x1000076C1: malloc (vg_replace_malloc.c:303)
==601==    by 0x100000941: pgmRead (pgmUtility.c:26)
==601==    by 0x100001A79: main (main.c:112)
==601== 
==601== Invalid read of size 8
==601==    at 0x100000B03: pgmDrawCircle (pgmUtility.c:43)
==601==    by 0x100001AB7: main (main.c:114)
==601==  Address 0x100820e30 is 0 bytes after a block of size 2,560 alloc'd
==601==    at 0x1000076C1: malloc (vg_replace_malloc.c:303)
==601==    by 0x100000941: pgmRead (pgmUtility.c:26)
==601==    by 0x100001A79: main (main.c:112)
==601== 
==601== Invalid read of size 8
==601==    at 0x100000C20: pgmDrawCircle (pgmUtility.c:57)
==601==    by 0x100001AB7: main (main.c:114)
==601==  Address 0x100820e30 is 0 bytes after a block of size 2,560 alloc'd
==601==    at 0x1000076C1: malloc (vg_replace_malloc.c:303)
==601==    by 0x100000941: pgmRead (pgmUtility.c:26)
==601==    by 0x100001A79: main (main.c:112)
==601== 

Successfully wrote image to new file

==601== Invalid read of size 8
==601==    at 0x1000012BE: pgmWrite (pgmUtility.c:123)
==601==    by 0x100001AE3: main (main.c:115)
==601==  Address 0x100820e30 is 0 bytes after a block of size 2,560 alloc'd
==601==    at 0x1000076C1: malloc (vg_replace_malloc.c:303)
==601==    by 0x100000941: pgmRead (pgmUtility.c:26)
==601==    by 0x100001A79: main (main.c:112)
==601== 
==601== 
==601== HEAP SUMMARY:
==601==     in use at exit: 1,267,658 bytes in 1,065 blocks
==601==   total heap usage: 1,149 allocs, 84 frees, 1,284,570 bytes allocated
==601== 
==601== LEAK SUMMARY:
==601==    definitely lost: 726,160 bytes in 382 blocks
==601==    indirectly lost: 0 bytes in 0 blocks
==601==      possibly lost: 0 bytes in 0 blocks
==601==    still reachable: 507,136 bytes in 263 blocks
==601==         suppressed: 34,362 bytes in 420 blocks
==601== Rerun with --leak-check=full to see details of leaked memory
==601== 
==601== For counts of detected and suppressed errors, rerun with: -v
==601== ERROR SUMMARY: 111418 errors from 5 contexts (suppressed: 0 from 0)

如果需要更多信息,请与我们联系。

以下是获取错误的方法:

int ** pgmRead( char **header, int *numRows, int *numCols, FILE *in  ){

   int i, j;
   for(i = 0; i < 4; i++)
      fgets(header[i], 100, in);

   rewind(in);
   char x[100];
   fgets(x,100, in);
   fgets(x, 100, in);
   int A=0;
   fscanf(in, "%d %d", numCols, numRows);
   fscanf(in, "%d",&A);
   int ** pixels = malloc( *numCols * sizeof(int*));
   for(i = 0; i < *numCols; i++){
      pixels[i] = malloc(sizeof(int) * (*numRows));
   }
   for(j = 0; j < *numRows; j++){
      for(i = 0; i < *numCols; i++){
         fscanf(in, "%d", &pixels[i][j]);
      }
   }
   return pixels;
}

我确实将它释放出来,因为我称之为

pixels = pgmRead(header, &numRows, &numCols, fp);

然后我在主

中释放(像素)

2 个答案:

答案 0 :(得分:1)

BTW,在行

int ** pixels = (int **) malloc( *numCols * sizeof(int));

malloc的论点对我来说不合适。

int ** pixels = malloc( numCols * sizeof(int*));

看起来就像你应该使用的那样。

<强>更新

要取消分配数据,您必须按照free拨打malloc的确切拨打次数。

for(i = 0; i < numCols; i++){
   free(pixels[i];
}
free(pixels);

答案 1 :(得分:0)

代码不能“只是”释放(像素);

这是你的问题所说的。

而且每个指向malloc到像素[i]的指针也必须传递给free。即。

for( i = 0; i < numcols; i++ )  free( pixels[i];

然后终于:

free( pixels );

请注意.pgm图像文件的格式不是发布的代码所期望的格式。

建议阅读:http://netpbm.sourceforge.net/doc/pgm.html

http://en.wikipedia.org/wiki/Netpbm_format

另请注意,图像布置在行彼此跟随的像素行(列)中。

发布的代码将图像视为列出第一列像素,然后是下一列,等等。这是不正确的。