1

我正在使用 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);
4

3 回答 3

1

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

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

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

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

于 2013-02-27T12:11:51.907 回答
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));
}
于 2013-02-27T10:23:00.153 回答
1

为什么你们都坚持单独分配数组的每一行?只需制作一个大型分配器和一个 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] vs [y][x] 迭代缓存问题。
于 2013-02-27T10:24:38.970 回答