使用函数的免费双指针

时间:2013-10-22 19:14:11

标签: c pointers malloc free

所以我使用以下函数为双指针创建并分配了内存:

void mallocDoubleArr(double ***arr, int size)
{
    printf("Here: %d", size);
    int i, j;

    *arr = malloc(size * sizeof(double*));

    for(i = 0; i < size; i++)
    {
        (*arr)[i]= malloc(size*sizeof(double));
        for (j = 0; j < size; j++)
        {
            (*arr)[i][j] = 0;
        }
    }
}

我用这个函数调用了函数:

    double **G; //Create double pointer to hold 2d matrix

    mallocDoubleArr(&G, numNodes);

现在我的问题是如何编写一个释放内存的函数?

我试过这样的事情:

void freeDoubleArr(double ***arr, int size)
{
    int i, j;

    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
            free((arr)[i]);
    free(arr);
}

2 个答案:

答案 0 :(得分:3)

您似乎希望将指针的地址传递给freeDoubleArr,如freeDoubleArr(&G, numnodes)(我宁愿称之为deleteDoubleArr)。然后你需要

void freeDoubleArr(double ***arrptr, int size)
{
   double** arr = *arrptr;
   for (int i = 0; i < size; i++)
      free(arr[i]);
   free (arr);
   *arrptr = NULL;
}

但是,您可以确定您的方阵不表示为指向数组的指针数组,而是表示为普通数组。也许使用flexible array members(C99及更高版本),如

struct matrix_st {
   unsigned size;
   double arr[]; /* flexible array of size*size elements */
};

可能很有用,arr实际上是size*size个元素的数组(每个都是double)。

然后您可以定义快速访问和mutator内联函数。

inline double get_element(struct matrix_st *m, int i, int j) {
   assert (m != NULL);
   unsigned s = m->size;
   assert (i>=0 && i<s && j>=0 && j<s);
   return m->arr[s*i+j];
}

inline void put_element(struct matrix_st* m, int i, int j, double x) {
   assert (m != NULL);
   unsigned s = m->size;
   assert (i>=0 && i<s && j>=0 && j<s);
   m->arr[i*s+j] = x;
}

优化时,使用<assert.h>(请参阅assert(3) ...)并使用-DNDEBUG进行编译,上述访问者get_element和mutator put_element会或许比你的代码更快。

矩阵创建只是(创建一个归零矩阵):

struct matrix_st* make_matrix (unsigned size) {
   struct matrix_st* m = malloc(sizeof (struct matrix_st)
                                + size*size*sizeof(double);
   if (!m) { perror("malloc"); exit(EXIT_FAILURE); };
   m->size = size;
   memset(m->arr, 0, sizeof(double)*size*size);
   return m;
 }

然后,用户可以只使用一次free来释放这样的矩阵。

BTW,如果在Linux上编码,请使用gcc -Wall -g进行编译,并使用valgrind内存泄漏检测器和gdb调试器。

答案 1 :(得分:1)

您的免费代码不应该更像以下内容:

void freeDoubleArr(double ***arr, int size)
{
    int i;

    for (i = 0; i < size; i++)
        free((*arr)[i]);
    free(*arr);
}

您甚至没有在任何地方使用'j'参数,因此内部for循环将导致它尝试释放相同的内存大小时间区域。你还需要取消引用传入的指针来获取malloc的指针,就像你将malloc的结果分配到它时一样。

此外,如果说某些内容无法包含您所看到的具体错误或者您认为哪些错误无法正常运行,那将非常有用。