无论出于何种原因,我在尝试释放我创建的2D数组时遇到以下错误:
`./a.out':free()出错:下一个大小无效(快):0x0000000001759310 ***中止(核心转储)
我打印出数组的内容,它们是正确的,我可以访问所有元素。但是,我还没有能够释放它。通过释放循环时发生错误,即释放double *。非常感谢任何帮助。
谢谢!
以下是代码:
/*allocation*/
double **block_mat = (double **) malloc (sizeof(double *) * num_blocks);
int i;
for (i = 0; i <num_blocks; i++){
block_mat[i] = (double *) malloc (sizeof(double) * s);
}
/*freeing*/
for (i = 0; i < num_blocks; i++){
free(block_mat[i]);
}
自由(block_mat);
编辑: 发现错误!我分配内存不足...所以当我打印出我的数组时,看起来一切都很好......我分配了大小为s的数组,但是使用的是s ^ 2。谢谢大家!
答案 0 :(得分:1)
你确定这些指针都是用不同的mallocs分配的吗?
free(my_matrix->vals);
free(my_matrix->cols);
free(my_matrix->rows);
free(my_matrix);
for (i = 0; i < num_blocks; i++){
free(block_mat[i]);
}
free(block_mat);
如果其中两个是相同的指针,那么你试图释放两次。
答案 1 :(得分:1)
您为每个s
分配block_mat[i]
个双打空间。稍后,您可以访问
block_mat[i][block_index] = 0;
block_index++;
但是你永远不会检查block_index
是否超出界限。
如果你写的超出s
分配的双精度数,你可能会破坏后续指针的内部控制数据,这通常放在malloc
返回的指针之前,并且必须完整free
。
答案 2 :(得分:0)
这是不正确的:
free(my_matrix);
free(my_matrix->vals);
free(my_matrix->cols);
free(my_matrix->rows);
订单应至少如下:
free(my_matrix->vals);
free(my_matrix->cols);
free(my_matrix->rows);
free(my_matrix);
答案 3 :(得分:0)
您有几个可能影响分配的问题。第一个,如果对strtol
的调用失败怎么办?
s = (int)strtol(argv [3], &ptr, 10);
您应该检查转换:
#include <errno.h>
...
else {
errno = 0;
long tmp = strtol(argv [3], &ptr, 10);
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (ptr == argv[3]) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
s = (int)tmp;
}
接下来,随着您的分配和免费,您走在正确的轨道上,但不会投出malloc的回报。转换返回只会增加难以调试错误的可能性。在分配指向指针的指针时,需要根据需要分配尽可能多的指针。 (num_blocks
)在你的情况下。在计算分配的大小时,您可以简单地取消引用正在分配的变量,这再次减少了出错的可能性:
int i;
double **block_mat = malloc (sizeof *block_mat * num_blocks);
/* check allocation for failure */
for (i = 0; i <num_blocks; i++){
block_mat[i] = malloc (sizeof **block_mat * s);
/* check allocation for failure */
}
/*freeing*/
for (i = 0; i < num_blocks; i++){
free (block_mat[i]);
}
free(block_mat);
注意:在开始引用元素之前,必须初始化block_mat
中的所有值,以防止以后取消分配未赋值的值。 (例如double result = block_mat[i][j] * Pi;
)考虑添加:
block_mat[i] = malloc (sizeof **block_mat * s);
/* check for failure */
block_mat[i] = 0.0;
注意:在分配数字矩阵时,请考虑使用calloc
而不是malloc
,因为它会将所有值初始化为'0'
并防止无意中取消引用未分配的值 - 这是未定义的行为。使用calloc
您将拥有:
int i;
double **block_mat = calloc (num_blocks, sizeof *block_mat);
/* check allocation for failure */
for (i = 0; i <num_blocks; i++){
block_mat[i] = calloc (s, sizeof **block_mat);
/* check allocation for failure */
}
/*freeing*/
for (i = 0; i < num_blocks; i++){
free (block_mat[i]);
}
free(block_mat);
注意:当s
大于1
时,您将在每个指针处为多个双倍分配空间。注意事项阻止您这样做,但您负责处理每个值的偏移量。 (例如result = *(block_mat[i] + j + n * sizeof **block_mat) * Pi;
,其中n为0 <= n < s
)如果要在每个指针中存储多个双精度数,请考虑使用pointer-to-struct
。 E.g:
typedef struct point {
double x;
double y;
double z;
} point;