在C中释放2D数组

时间:2015-04-26 07:18:53

标签: c arrays malloc free

无论出于何种原因,我在尝试释放我创建的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。谢谢大家!

4 个答案:

答案 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;