valgrind 在我的 c 程序中显示内存泄漏(两个版本)

问题描述 投票:0回答:1
int main()
{             
   double (*arr)[COLS] = (double*)malloc(sizeof(*arr) * ROWS);
   assert(arr!= NULL);
   for (int i = 0; i < ROWS; i++)
   {
      for (int j = 0; j < COLS; j++)
      {
         arr[i][j] = 0.0;   
      }
   }
   
   //diagonal
   for (int i = 0; i < ROWS; i++)
   {
      arr[i][i] = 4;
   }

   //SUB diagonal
   for (int i = 1; i < ROWS; i++)
   {
      arr[i][i - 1] = -1;
   }

   //top diagonal
   for (int i = 0; i < ROWS; i++)
   {
      arr[i][i + 1] = -1;
   }

   //printing  the whole array
   for (int i = 0; i < ROWS; i++)
   {
      for (int j = 0; j < COLS; j++)
      {
         printf("%lf ", arr[i][j]);
      }
      printf("\n");
   }

   printf("###################\n");
   //RHS
   double* b = malloc(sizeof(double) * ROWS);
   assert(b != NULL);
   for (int j = 0; j < ROWS; j++) {
      b[j] = 1;
   }

   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", b[j]);
   } 

   printf("--------------------\n");

   //x_old
   double* x_old = malloc(sizeof(double) * ROWS);
   assert(x_old != NULL);
   for (int j = 0; j < ROWS; j++) {
      x_old[j] = 0.0;
   }
   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", x_old[j]);
   }
   printf("******************\n");

   //x_new
   double* x_new = malloc(sizeof(double) * ROWS);
   assert(x_new != NULL);
   for (int j = 0; j < ROWS; j++) {
      x_new[j] = 0.0;
   }
   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", x_new[j]);
   }
   printf("^^^^^^^^^^^^^^^^^^^^^\n");
    
   free((double*)arr);
   free(b);
   free(x_old);
   free(x_new);
   return 0;
}

和第二个版本

int main()
{ 
   //allocation
   
   double** arr = malloc(ROWS * sizeof(*arr));//pointer to an array with rows
   if(arr != NULL){
      for (int i = 0; i < ROWS; i++) {
         //allocate memory for each row
         arr[i] = malloc(COLS * sizeof(*arr[i]));
         assert(arr[i] != NULL);
      }
   }
   
  
   //diagonal
   for (int i = 0; i < ROWS; i++)
   {
      arr[i][i] = 4;
   }

   //subdiagonal
   for (int i = 1; i < ROWS; i++)
   {
      arr[i][i - 1] = -1;
   }

   //top diagonal
   for (int i = 0; i < ROWS; i++)
   {
      arr[i][i + 1] = -1;
   }

   //printing  the whole array
   for (int i = 0; i < ROWS; i++)
   {
      for (int j = 0; j < COLS; j++)
      {
         printf("%lf ", arr[i][j]);
      }
      printf("\n");
   }

   printf("###################\n");

   //RHS
   double* b= malloc(sizeof(double) * ROWS);
   assert(b != NULL);
   for (int j = 0; j < ROWS; j++) {
      b[j] = 1;
   }

   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", b[j]);
   }

   printf("--------------------\n");

   //x_old
   double* x_old = malloc(sizeof(double) * ROWS);
   assert(x_old != NULL);
   for (int j = 0; j < ROWS; j++) {
      x_old[j] = 0.0;
   }
   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", x_old[j]);
   }
   printf("******************\n");

   //x_new
   double* x_new = malloc(sizeof(double) * ROWS);
   assert(x_new != NULL);
   for (int j = 0; j < ROWS; j++) {
      x_new[j] = 0.0;
   }
   for (int j = 0; j < ROWS; j++) {
      printf("%lf\n", x_new[j]);
   }
   printf("^^^^^^^^^^^^^^^^^^^^^\n");
      
   free(x_new);
   free(x_old);
   free(b); 
   //in this loop the mistake
   for(int i=0;i<ROWS;i++){
      if(array[i] != NULL){
         free(array[i]);
         arr[i] = NULL;
      }
   }
   free(arr); 
   return 0;
}
the output of valgrind in both cases
==9955== 
==9955== HEAP SUMMARY:
==9955==     in use at exit: 1,050 bytes in 33 blocks
==9955==   total heap usage: 35 allocs, 2 frees, 2,074 bytes allocated
==9955== 
==9955== 27 bytes in 1 blocks are still reachable in loss record 1 of 4
==9955==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955==    by 0x491458E: strdup (strdup.c:42)
==9955==    by 0x10F43C: ??? (in /usr/bin/dash)
==9955==    by 0x11EB69: ??? (in /usr/bin/dash)
==9955==    by 0x10CB65: ??? (in /usr/bin/dash)
==9955==    by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955== 
==9955== 31 bytes in 1 blocks are still reachable in loss record 2 of 4
==9955==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955==    by 0x11E154: ??? (in /usr/bin/dash)
==9955==    by 0x11EB69: ??? (in /usr/bin/dash)
==9955==    by 0x10CB65: ??? (in /usr/bin/dash)
==9955==    by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955== 
==9955== 32 bytes in 1 blocks are still reachable in loss record 3 of 4
==9955==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955==    by 0x11E004: ??? (in /usr/bin/dash)
==9955==    by 0x11EB44: ??? (in /usr/bin/dash)
==9955==    by 0x10CB65: ??? (in /usr/bin/dash)
==9955==    by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955== 
==9955== 960 bytes in 30 blocks are still reachable in loss record 4 of 4
==9955==    at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==9955==    by 0x11E004: ??? (in /usr/bin/dash)
==9955==    by 0x11EADF: ??? (in /usr/bin/dash)
==9955==    by 0x10CB65: ??? (in /usr/bin/dash)
==9955==    by 0x4895D8F: (below main) (libc_start_call_main.h:58)
==9955== 
==9955== LEAK SUMMARY:
==9955==    definitely lost: 0 bytes in 0 blocks
==9955==    indirectly lost: 0 bytes in 0 blocks
==9955==      possibly lost: 0 bytes in 0 blocks
==9955==    still reachable: 1,050 bytes in 33 blocks
==9955==         suppressed: 0 bytes in 0 blocks
==9955== 
==9955== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
memory malloc valgrind dynamic-memory-allocation
1个回答
0
投票

我建议不要使用 C,除非您被迫拥有最低公分母接口。您将能够使用像

Eigen
Armadillo
这样的 C++ 库来完成类似的事情,而无需手动分配内存,而且它们的速度甚至会与容易出错的重新发明轮子一样快。

不要将

malloc
的返回值投射到 C 中。

考虑使用

memset
来初始化 C 中的值(或使用可以使用构造函数自动初始化的 C++)。

您发布的 Valgrind 日志适用于您的 shell,而不是您的测试 exe。您需要做两件事之一。

修改您的包装器脚本,以便它在 Valgrind 中运行您的测试 exe。

或者运行 Valgrind,以便它也跟踪子进程。比如说

valgrind --trace-children=yes --log-file=memcheck.%p.log wrapper.dsh

这将为每个进程生成一个日志文件。您需要找到哪一个适合您的测试 exe,然后查看它。

© www.soinside.com 2019 - 2024. All rights reserved.