Valgrind封锁丢失,在哪里免费?

时间:2016-11-16 13:26:10

标签: c linux valgrind

我正在尝试做一个程序,它能够乘以运算符首选项等矩阵表达式。 我完成了程序并且它可以工作,但是在完成后我在valgrind中遇到了一些错误。很明显,这是因为在指向下一个矩阵的指针附近使用了free()。但我无法弄清楚如何正确地做到这一点。有人可以帮助我,我将非常感激。

这是我的代码

#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();

1 个答案:

答案 0 :(得分:0)

我看到的第一个是

struct MtrixObject *newMatrixObject (size_t n, size_t m) {

//...

retVal->pointToNext = malloc(sizeof(struct MatrixObject*));
if (retVal->pointToNext == NULL) {
    free (retVal);
    return NULL;
}

retVal的编号在错误检查块中永远不会自由。请记住,释放结构不会释放由malloc

初始化的任何变量

在你的主体中,矩阵或者realMatrix不是免费的。 看起来你正在创建一个默认矩阵,actualMatrix,然后编辑它然后设置一个指针pointToNext来指向编辑过的矩阵。之后,您将actualMatrix设置回默认矩阵。 (这是我在这里看到的LinkedList吗?)

这意味着你有一系列基础不自由的matricies。你应该尝试

struct MatrixObject *temp;
while (matrix != NULL) {
    temp = matrix.pointToNext;
    free(matrix);
    matrix = temp;
}

这将遍历第一个矩阵之后的所有矩阵并释放它们。

请注意,我不知道printMatrix的功能,因为它从未在您的代码中执行过。可能是你释放了那里的矩阵。

还有最后一条评论,因为你在方法中调用了errorHandle(),如果有一些错误,你很可能没有释放一些mallocs

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();
    }
//...

这里调用了errorHandle,但是你几乎没有办法释放newNumbers,因为它从未作为引用传入。这意味着它只会浮动而永远不会干净。

我建议在errorHandle

之后分配newNumbers