gpt4 book ai didi

c - Valgrind block 丢失,从哪里释放?

转载 作者:太空宇宙 更新时间:2023-11-04 12:39:40 24 4
gpt4 key购买 nike

我正在尝试编写一个程序,该程序能够根据运算符偏好等对矩阵表达式进行乘法和加法运算。我完成了程序并且它可以工作,但是完成后我在 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();

最佳答案

我首先看到的是

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

//...

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

retVal 的编号在错误检查 block 中从未空闲过。请记住,释放一个结构体并不会释放由 malloc 初始化的任何内部变量

在您的 main 中,matrix 或 actualMatrix 不是免费的。看起来您正在创建默认矩阵 actualMatrix 并对其进行编辑,然后设置指针 pointToNext 以指向已编辑的矩阵。之后,您将 actualMatrix 设置回默认矩阵。 (这是我在这里看到的 LinkedList 吗?)

这意味着你有一个矩阵链,最后不是免费的。你应该试试

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

关于c - Valgrind block 丢失,从哪里释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40633352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com