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