0

したがって、次の関数を使用して、ダブルポインター用のメモリを作成して割り当てました。

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);
}
4

2 に答える 2

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;
}

ただし、正方行列が配列へのポインターの配列としてではなく、単純な配列として表されると判断することもできます。おそらく、(C99 以降の)柔軟な配列メンバーを使用して

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

arr実際にはsize*size要素の配列(それぞれが a )である規則を使用すると、便利な場合があり  doubleます。

次に、クイック アクセスとミューテーター インライン関数を定義できます。

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(3) ...<assert.h>を参照)を使用して最適化し、上記のアクセサーとミューテーターを使用してコンパイルすると、コードよりもおそらく高速になります。-DNDEBUGget_elementput_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;
 }

次に、ユーザーは を 1 回呼び出すだけで、freeそのような行列を解放できます。

ところで、Linux でコーディングする場合は、valgrindメモリ リーク ディテクターとgdbデバッガーでコンパイルしgcc -Wall -gて使用します。

于 2013-10-22T19:20:25.253 に答える
1

無料のコードは次のようにすべきではありません。

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

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

どこでも「j」パラメーターを使用していないため、内側の for ループにより、同じメモリ サイズの領域を何度も解放しようとします。また、malloc の結果に代入するときと同じ方法で、渡されたポインターを逆参照して、malloc されたポインターを取得する必要があります。

また、何かが機能しないと言う場合に、表示されている特定のエラーや、正しく機能していないと思われる原因を含めると便利です。

于 2013-10-22T19:33:23.427 に答える