C矩阵行列式计算 - 内存泄漏

时间:2016-10-16 09:27:41

标签: c matrix memory-leaks

我的程序中仍然存在内存泄漏,计算矩阵行列式。我不知道如何解决它。我已经标记了valgrind发现无效的代码行。 Matrix是从文本文件加载的。文件样本(第一个数字是矩阵的大小): 3 1 2 3 4 5 6 7 8 9 Valgrind输出:

==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 个答案:

答案 0 :(得分:1)

你的第99行没用:

  double** minor = (double**)calloc(n, sizeof(double*));  // <---- Line 99
  • 如果n==1n==2,您要么返回另一个矩阵:内存泄漏:指针未使用,未释放
  • 如果minor:内存泄漏:指针被覆盖,
  • 或者您在循环中覆盖n>2

只需删除它,你就可以了。