我使用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);
valgrind输出表明您正在释放matrix
,而不是其成员。对于每个分配,必须调用一次free
:
for (i=0; i<2; i++) {
free(matrix[i]);
}
free(matrix);
注意,如果使用calloc
分配内存,可以简化代码,避免initialize to zero循环:
int **matrix = malloc(2*sizeof(int*));
for (i=0; i<2; i++){
matrix[i] = calloc(size*sizeof(int));
}
就像simon说的,听起来你没有释放单个数组元素。
如果您正在使用C99编译器或C2011编译器支持变长数组,您可以简化一些事情,并使用单个malloc
和free
调用,如下所示:
int size;
...
int (*matrix)[size] = malloc(2 * sizeof *matrix);
...
// do stuff with matrix[i][j]
...
free (matrix);
如果你使用的编译器不支持VLAs,你要么必须做两步分配和释放,要么像Darius的回答那样分配一个1-d数组和映射索引。
为什么你们都坚持要分别分配数组的每一行?只需要创建一个大的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] vs [y][x]迭代缓存问题。