【问题标题】:valgrind memory lost in array of pointesvalgrind 内存在点数组中丢失
【发布时间】:2013-02-27 10:18:53
【问题描述】:

我正在使用 Valgrind 调试我的 c 程序。 我收到的错误是:

==2765== 8,000 bytes in 2 blocks are definitely lost in loss record 1 of 1
==2765==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==2765==    by 0x404123: main (mycode.cpp:352)

这是第 352 行附近的代码:

int **matrix;
matrix = (int**)malloc(2*sizeof(int*));
for (i=0; i<2; i++){
    matrix[i] = (int*)malloc(size*sizeof(int)); //line 352
}
for (i=0; i<2; i++){ //inizialization
    for (k=0; k<size; k++)
        matrix[i][k] = 0;
}

这是我为矩阵分配内存的方式。 这有什么问题?


更新: 在程序结束时,我使用了:

free(matrix);

【问题讨论】:

  • 您发布的代码没有问题。错误出现在释放matrix 的代码中。您能否更新您的问题以显示这一点?
  • 我想我之前已经说过了,但我会再说一遍:please don't cast the return value of malloc(), in C
  • 我按照 simonc 的要求更新了问题。谢谢放松:),我会仔细阅读你的帖子。

标签: c malloc valgrind


【解决方案1】:

valgrind 输出表明您正在释放matrix,但不是它的成员。对于每次分配,您必须致电free

for (i=0; i<2; i++) {
    free(matrix[i]);
}
free(matrix);

请注意,如果您使用 calloc 分配内存,您可以简化代码,避免初始化为零循环:

int **matrix = malloc(2*sizeof(int*));
for (i=0; i<2; i++){
    matrix[i] = calloc(size*sizeof(int));
}

【讨论】:

    【解决方案2】:

    就像 simonc 所说,听起来您没有释放单个数组元素。

    如果您使用的是支持可变长度数组的 C99 编译器或 C2011 编译器,您可以稍微简化一下,并使用单个 mallocfree 调用,如下所示:

    int size;
    ...
    int (*matrix)[size] = malloc(2 * sizeof *matrix);
    ...
    // do stuff with matrix[i][j]
    ...
    free (matrix);
    

    如果您使用的编译器不支持 VLA,您要么必须执行两步分配和解除分配,要么按照 Darius 的回答分配一维数组和映射索引。

    【讨论】:

      【解决方案3】:

      为什么你们都坚持单独分配数组的每一行?只需创建一个大的 alloc 和一个 getter/setter 方法!

      #define ARR_COLUMNS 10
      #define ARR_ROWS 10
      
      int* arr = calloc (ARR_COLUMNS * ARR_ROWS, sizeof(int));
      
      int get(int* arr, int x, int y) {
        if (x<0 || x>= ARR_COLUMNS) return 0;
        if (y<0 || y>= ARR_ROWS) return 0;
        return arr[ARR_COLUMNS*y+x];
      }
      
      void set (int* arr, int x, int y, int val) {
        if (x<0 || x>= ARR_COLUMNS) return;
        if (y<0 || y>= ARR_ROWS) return;
        arr[ARR_COLUMNS*y+x] = val;
      }
      

      这样做你会:

      • 为自己节省昂贵的分配和释放
      • 内存碎片较少
      • 简化可能的 realloc 调用
      • 确保数据得到更好的缓存和访问,没有常见的 [x][y] 与 [y][x] 迭代缓存问题。

      【讨论】:

      • 太棒了!但我想知道如果我必须同时增加行数和列数,它是否也有效。
      • 对于 2D 数组重新分配,您必须编写自己的函数,将 memmove 数组的块重新分配到它们的新位置并将数组的“新”部分归零。这相当简单,但必须小心操作。
      猜你喜欢
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-22
      • 2019-12-15
      相关资源
      最近更新 更多