2016-10-16 10 views
1

行列の行列式を計算するプログラムでメモリリークがまだ発生しています。私はそれを修正する方法を知らない。私はvalgrindが無効であると判断したコード行をマークしました。マトリックスはテキストファイルから読み込まれます。ファイルのサンプル(最初の数は、行列のサイズである): 3 1 2 3 4 5 6 7 8 9 Valgrindの出力:C行列の行列式の計算 - メモリリーク

==3292== Memcheck, a memory error detector 
==3292== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==3292== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info 
==3292== Command: ./macierz 
==3292== 
Matrix Size: 4 
1.000000 2.000000 3.000000 4.000000 
4.000000 5.000000 6.000000 5.000000 
7.000000 8.000000 15.000000 5.000000 
5.000000 4.000000 6.000000 7.000000 
Determinant: 303.000000 
==3292== 
==3292== HEAP SUMMARY: 
==3292==  in use at exit: 104 bytes in 8 blocks 
==3292== total heap usage: 48 allocs, 40 frees, 6,864 bytes allocated 
==3292== 
==3292== 24 bytes in 3 blocks are definitely lost in loss record 1 of 3 
==3292== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so) 
==3292== by 0x400BCB: det(double**, int) (main.c:99) 
==3292== by 0x400C9E: det(double**, int) (main.c:116) 
==3292== by 0x400C9E: det(double**, int) (main.c:116) 
==3292== by 0x400D7A: main (main.c:140) 
==3292== 
==3292== 32 bytes in 1 blocks are definitely lost in loss record 2 of 3 
==3292== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so) 
==3292== by 0x400BCB: det(double**, int) (main.c:99) 
==3292== by 0x400D7A: main (main.c:140) 
==3292== 
==3292== 48 bytes in 4 blocks are definitely lost in loss record 3 of 3 
==3292== at 0x4C2FB55: calloc (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so) 
==3292== by 0x400BCB: det(double**, int) (main.c:99) 
==3292== by 0x400C9E: det(double**, int) (main.c:116) 
==3292== by 0x400D7A: main (main.c:140) 
==3292== 
==3292== LEAK SUMMARY: 
==3292== definitely lost: 104 bytes in 8 blocks 
==3292== indirectly lost: 0 bytes in 0 blocks 
==3292==  possibly lost: 0 bytes in 0 blocks 
==3292== still reachable: 0 bytes in 0 blocks 
==3292==   suppressed: 0 bytes in 0 blocks 
==3292== 
==3292== For counts of detected and suppressed errors, rerun with: -v 
==3292== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0) 

コード:

#include <stdio.h> 
#include <stdlib.h> 

void displayMatrix(double** matrix, int n){\ 
    puts("DISPLAYING matrix"); 
    int i,j; 
    for(i = 0; i<n; i++){ 
     for(j = 0; j<n; j++){ 
      printf("%f ", matrix[i][j]); 
     } 
     puts(""); 
    } 
} 
int findSize(FILE *fp){ 

    int n; 
    fscanf(fp,"%i\n", &n); 
    printf("Matrix Size: %i\n", n); 
    return n; 
} 
void deleteMatrix(double** matrix, int n){ 

    int i; 
    for(i = 0; i < n; i++) 
     free(matrix[i]); 
    free(matrix); 
} 
double** createMatrix(FILE* fp, int n){ 

    double** matrix = (double **)calloc(n, sizeof(double*)); 
    if(matrix == NULL){ 
     puts("Allocation error"); 
     exit(1); 
    } 

    int i, j; 
    double num; 
    for(i = 0; i<n; i++){ 

     matrix[i] = (double*)calloc(n, sizeof(double)); 

     for(j = 0; j<n; j++){ 
      fscanf(fp, "%lf ", &num); 
      matrix[i][j] = num; 
      printf("%f ", matrix[i][j]); 
     } 
     puts(""); 
    } 
    return matrix; 
} 
double** createMinor(double** matrix, int n, int banned){ 

    double** minor = (double**)calloc(n, sizeof(double*)); 
    int i,j; 
    int i2 = 0, j2 = 0; 

    for(i=0; i<n; i++){ 
     minor[i] = (double*)calloc(n, sizeof(double)); 

     for(j=0; j<n; j++){ 

      if(i != 0 && j != banned){ 
       if(j2<n-1){ 
        minor[i2][j2] = matrix[i][j]; 
        j2++; 
       }else{ 
        i2++; 
        minor[i2][0] = matrix[i][j]; 
        j2 = 1; 
       } 
      } 
     } 
    } 
    return minor; 
} 
double det(double** matrix, int n){ 

    double sum = 0.0; 
    double sign = 1.0; 
    int i; 

    double** minor = (double**)calloc(n, sizeof(double*)); // <---- Line 99 
    if(n==1) 
     return matrix[0][0]; 
    if(n==2) 
     return matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0]; 

    for(i=0; i<n; i++){ 

     //copying submatrix to minor 
     minor = createMinor(matrix, n, i); 
     //----------- 

     sum += sign*matrix[0][i]*det(minor,n-1-i); // <--------- Line 116 
     sign = -sign; 

     deleteMatrix(minor,n); 
    }; 

    return sum; 
} 
int main(int argc, char* argv[]){ 

    const char* filename = "plik.txt"; 

    FILE *fp = fopen(filename, "r"); 
    if(fp == NULL){ 
     puts("Error - opening file"); 
     exit(1); 
    } 

    double size = findSize(fp); 
    double** matrix = createMatrix(fp, size); 
    double deter = det(matrix, size);  // <-------- Line 140 

    printf("Determinant: %f\n", deter); 

    deleteMatrix(matrix, size); 
    fclose(fp); 
    return 0; 
} 

答えて

1

あなたのライン99は無用です:

double** minor = (double**)calloc(n, sizeof(double*)); // <---- Line 99 
  • n==1またはの場合は別の行列を返します。 10:メモリリーク:使用されていないポインタ、
  • n>2場合は、ループ内でminor値を上書きしている解放されていない:メモリリークは:ポインタはちょうどそれを削除

を上書きし、あなたは大丈夫だろうが。