行列式を乗算して演算子の優先順位などを追加できるようなプログラムを作成しようとしています。 私はプログラムを完了し、それは動作しますが、完了後にvalgrindにいくつかのエラーがあります。これは、次の行列へのポインタの近くでfree()の悪い使い方が原因であることは明らかです。しかし、私はそれを正しく行う方法を考え出すことができません。誰かが私を助けてください、私はそれに非常に感謝します。Valgrindブロックが失われ、どこから解放されますか?
は、ここに私のコードここ
#include <stdio.h>
#include <stdlib.h>
#include "files.h"
struct MatrixObject *matrix;
struct MatrixObject{
size_t rows;
size_t columns;
int *numbers;
struct MatrixObject *pointToNext;
char sign;
};
struct MatrixObject *newMatrixObject (size_t n, size_t m) {
struct MatrixObject *retVal = malloc (sizeof (struct MatrixObject));
if (retVal == NULL)
return NULL;
retVal->numbers = malloc (n * m * sizeof (int*));
if (retVal->numbers == NULL) {
free (retVal);
return NULL;
}
retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
if (retVal->pointToNext == NULL) {
free (retVal);
return NULL;
}
retVal->rows = n;
retVal->columns = m;
return retVal;
}
struct MatrixObject* getMatrixArray(){
struct MatrixObject *object;
int m, n;
if(scanf("%d %d", &n, &m) != 2){
errorHandle();
}
if(n<0 || m<0){
errorHandle();
}
object = newMatrixObject(n, m);
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
if(fscanf(stdin, "%d", &(object->numbers[(i*m)+j]))!=1){
errorHandle();
}
}
}
char temp;
int res;
while((res=fscanf(stdin, "%c", &temp))!=EOF){
if(res!=1){
errorHandle();
}
if(temp == '*' || temp == '+' || temp == '-'){
object->sign = temp;
object->pointToNext = getMatrixArray();
return object;
}
}
object->sign = 0;
object->pointToNext = 0;
return object;
}
void multiplyMatrix(struct MatrixObject *matrix1, struct MatrixObject *matrix2){
int newColumns = matrix2->columns;
int newRows = matrix1->rows;
int* newNumbers = malloc(newColumns * newRows * sizeof(*newNumbers));
int counter = 0;
if(matrix1->columns != matrix2->rows){
errorHandle();
}
for(int i = 0;i<newRows;i++){
for(int k = 0;k<newColumns;k++){
int sum = 0;
for(int j = 0;j<matrix1->columns;j++){
sum+= ((matrix1->numbers)[(i*matrix1->columns)+j]) * ((matrix2->numbers)[(j*matrix2->columns)+k]);
}
newNumbers[counter] = sum;
counter++;
}
}
struct MatrixObject mat = *matrix2;
free(matrix2->numbers);
free(matrix2);
matrix1->pointToNext = mat.pointToNext;
matrix1->sign = mat.sign;
free(matrix1->numbers);
matrix1->numbers = newNumbers;
matrix1->columns = newColumns;
matrix1->rows = newRows;
}
void addMatrix(struct MatrixObject *matrix1, struct MatrixObject *matrix2, char sign){
if(matrix1->columns != matrix2->columns || matrix1->rows != matrix2->rows){
errorHandle();
}
int columns = matrix1->columns;
int rows = matrix2->rows;
int* newNumbers = malloc(rows*columns*sizeof(*newNumbers));
for(int i = 0;i<rows;i++){
for(int j = 0;j<columns;j++){
if(sign == '+'){
newNumbers[i*columns + j] = matrix1->numbers[i*columns + j] + matrix2->numbers[i*columns + j];
}else{
newNumbers[i*columns + j] = matrix1->numbers[i*columns + j] - matrix2->numbers[i*columns + j];
}
}
}
struct MatrixObject mat = *matrix2;
free(matrix2->numbers);
free(matrix2);
matrix1->pointToNext = mat.pointToNext;
matrix1->sign = mat.sign;
free(matrix1->numbers);
matrix1->numbers = newNumbers;
}
int main(int argc, char *argv[])
{
struct MatrixObject *actualMatrix;
matrix = getMatrixArray();
actualMatrix = matrix;
while(actualMatrix->pointToNext != 0){
if(actualMatrix->sign == '*'){
multiplyMatrix(actualMatrix, actualMatrix->pointToNext);
}
else{
actualMatrix = actualMatrix->pointToNext;
}
}
printMatrix(matrix);
actualMatrix = matrix;
while(actualMatrix->pointToNext != 0){
if(actualMatrix->sign == '+' || actualMatrix->sign == '-'){
addMatrix(actualMatrix, actualMatrix->pointToNext, actualMatrix->sign);
}
}
printMatrix(matrix);
return 0;
}
は私valgrindのから出力される。ここで
==30650==
==30650== HEAP SUMMARY:
==30650== in use at exit: 88 bytes in 6 blocks
==30650== total heap usage: 17 allocs, 11 frees, 2,416 bytes allocated
==30650==
==30650== Searching for pointers to 6 not-freed blocks
==30650== Checked 65,936 bytes
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 1 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 2 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 3 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== 8 bytes in 1 blocks are definitely lost in loss record 4 of 6
==30650== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30650== by 0x400C59: newMatrixObject (main.c:32)
==30650== by 0x400D0F: getMatrixArray (main.c:54)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x400DC3: getMatrixArray (main.c:71)
==30650== by 0x40133F: main (main.c:177)
==30650==
==30650== LEAK SUMMARY:
==30650== definitely lost: 32 bytes in 4 blocks
==30650== indirectly lost: 0 bytes in 0 blocks
==30650== possibly lost: 0 bytes in 0 blocks
==30650== still reachable: 56 bytes in 2 blocks
==30650== suppressed: 0 bytes in 0 blocks
==30650== Reachable blocks (those to which a pointer was found) are not shown.
==30650== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==30650==
==30650== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
は、数直線のためのいくつかの情報です:
32: retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
54: object = newMatrixObject(n, m);
71: object->pointToNext = getMatrixArray();
177:matrix = getMatrixArray();
'retVal->番号=のmalloc(N×m個の*のはsizeof(INT *))後newNumbersため割り当てるお勧めします;' - > 'retVal->番号=のmalloc(N×m個*ヒットメモリ割り当ての数は呼び出しの数と一致しなければなりません(sizeof(int)); retVal-> pointToNext = malloc(sizeof(struct MatrixObject *));-> 'retVal-> pointToNext = NULL; ' – BLUEPIXY
現在はfree() 'よりも6つの割り当てがあります。問題を修正し、メモリリークがなくなります。 – user3629249
@BLUEPIXYおかげでたくさんの人がいました。これを解決するにはもう数時間かかります。私はあなたに1つ借りています:) – shade254