2016-10-16 34 views
1

Ich habe immer noch ein Speicherleck in meinem Programm, das Matrix Determinante berechnet. Ich weiß nicht, wie ich es beheben soll. Ich habe Codezeilen markiert, die valgrind für ungültig hält. Matrix wird aus einer Textdatei geladen. Probe einer Datei (erste Zahl ist die Größe der Matrix): 3 1 2 3 4 5 6 7 8 9 Valgrind Ausgabe:C Matrix Determinante berechnen - Speicherleck

==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) 

Code:

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

Antwort

1

Ihre Linie 99 ist nutzlos:

double** minor = (double**)calloc(n, sizeof(double*)); // <---- Line 99 
  • Entweder geben Sie eine andere Matrix zurück, wenn n==1 oder n==2: Speicherleck: nicht verwendeten Zeiger nicht befreit
  • oder Sie überschreiben minor Wert in der Schleife, wenn n>2: Speicherleck: pointer

einfach löschen sie überschreiben, werden Sie in Ordnung sein.

Verwandte Themen