2016-10-26 4 views
3

私は行列にメモリを割り当てるために、この機能を持っている:これらのmallocをどのように解放すればよいですか?

double **mmalloc(int r, int c){ 
    double **matrix = (double **)malloc((r)*sizeof(double*)); 
    for (int y = 0; y < r; y++){ 
     matrix[y] = (double *)malloc(c*sizeof(double)); 
    } 

    for (int y = 0; y < r; y++){ 
     for(int x = 0; x < c; x++){ 
      matrix[y][x] = 0; 
     } 
    } 
    return matrix; 
} 

はどのようにして返された行列のすべてのメモリを解放するのでしょうか?私はこの行列を解放する関数を持っています...行列の行を解放することはできますが、列を解放することはできません。

はここで解放機能です:

// Free all memory allocated for A 
void mfree(int r, int c, double **A){ 
    for (int y = 0; y < r; y++){ 
     free(A[y]); 
    } 
} 
+0

で生産コードで使用する前に、セカンドオピニオンを取得し、いつものように、[「ドンしてくださいしないでください"malloc'の戻り値をキャストする](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc);) – Quentin

答えて

3

あなたはこのために、すべての行を一つずつ、その後、最初に割り当てられた列(つまり、すべての行が含まれています)

void xfree(int r, int c, double **A){ 
    for (int y = 0; y < r; y++){ 
     free(A[y]); 
    } 
    free (A); 
} 

を解放する必要があります。各rowIを(ダブル)の列で構成されている

double ** (Initial allocation) 
    ↓ 
(double *)row0 → col0 col1 ... 
(double *)row1 → col0 col1 ... 
... 

。アレイの動的に割り当てられた配列が完全にフリー、念頭に置いてこれらのルールを維持するために

  • フリー Sの数は、割り当てに使用されたのmalloc Sの数に等しくなければなりません配列とその配列

  • 無料 dが偶然でも動作してもそれ以上使用できないと考えている(このような動作に続く動作はUnde罰金の行為)。たとえば、free(A)の場合は、free(A[i])を指定しないでください。A - ポインタのリストを含むメモリ空間 - これはもはや割り当てられない/使用可能ではないと考えられます。次いで

  • 従ってフリー最初の最も内側の要素( "含まれる"、例えばA[i]フリー "コンテナ"(例えばA)。

3
void xfree(int r, int c, double **A){ 
    for (int y = 0; y < r; y++){ 
      free(A[y]); 
    } 
    free(A) 
} 
+0

私は同意します、私はringøの提案を使用しました – ShaolinGOD

+0

私は間違って申し訳ありません。私は、Aは3DポインタだがAは2Dポインタであることを覚えてコードを書いた。私は私の答えを更新しました。 –

0

私は「カンニング」とちょうどあなたのデータの連続ブロックを割り当て、その後、第2のブロックは、あなたの行にあなたの配列アクセスを与えることになります。

int main(){ 

    int r=3; 
    int c=4; 

    double* data = malloc(sizeof(double) * r * c); 
    double** matrix = malloc(sizeof(double*) * r); 

    int i; 
    for (i=0;i<r;++i) { /* build the nice syntax accessor */ 
     matrix[i] = &data[i*c]; 
    } 
    for (i=0;i<(r*c);++i) { /* you can fill/clear the whole matrix in one loop too */ 
     data[i] = i; 
    }  

    // access data through matrix as a normal 2d array 
    matrix[2][2] = 1.1; 
    int x,y; 
    for (x=0;x<r;++x) { 
     for (y=0;y<c;++y) { 
      printf("[%1.1f]", matrix[x][y]); 
     } 
     printf("\n"); 
    } 

    // when done 
    free(matrix); 
    free(data); 

    return 0; 
} 

出力:

[0.0][1.0][2.0][3.0] 
[4.0][5.0][6.0][7.0] 
[8.0][9.0][1.1][11.0] 

1つの配列がちょうど他の配列を指し示しているので、2つの解放(あなたは両方とどちらのアクセスもしない限り)を呼び出す順序は重要ではないと思います。

構造体などにデータと行列を一緒に格納して、その構造体を取り込んで両方の領域(または両方の領域と構造体自体)を解放する関数を持つこともできます。

注:これは、コンパイルして作業するように見えたが、私は、生活のためにCを書く場合、私が見逃している何か

関連する問題