2016-10-16 38 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==1n==2:內存泄漏:指針不使用,不釋放
  • 或者你在循環覆蓋minor值,如果n>2:內存泄漏:指針覆蓋

只需把它刪掉,你會好起來的。