gpt4 book ai didi

c - Valgrind 报告无效的读取(和写入),但程序保持执行

转载 作者:行者123 更新时间:2023-11-30 16:17:08 24 4
gpt4 key购买 nike

我正在尝试解决大学考试的一项练习,但我遇到了一个内存错误,我无法真正弄清楚。我必须分配并初始化一个浮点矩阵,该矩阵具有一个名为 Mat 的结构作为矩阵。

typedef struct {
int rows;
int cols;
float **row_ptrs;
} Mat;

为此,我必须编写一个返回矩阵地址的函数。矩阵必须是指向矩阵行的指针数组:

Mat* Mat_alloc(int rows, int cols){
Mat* matrice = (Mat*)calloc(rows,sizeof(float**));
float** righe = (float**)calloc(cols,sizeof(float*));
(*matrice).row_ptrs=righe;
(*matrice).rows=rows;
(*matrice).cols=cols;
*righe = (float*)malloc(sizeof(float));
float* elem = *righe;
Mat* sav_ptr = matrice;
int i,j;
for(i=0;i<rows;i++){
printf("questa e' la riga: %d con indirizzo: %x\n\n",i,righe);
for(j=0;j<cols;j++){
*elem = 0.0;
printf("%f io sono l'elemento: %d con indirizzo: %x \n",*elem,j,elem);
elem++;
}
printf("\n");
righe++;
j=0;
}
return sav_ptr;
}

此外,我必须在调用并运行函数后释放所有内容,我编写了这个函数来执行此操作:

void Mat_free(Mat *m){
float** tofree = (*m).row_ptrs;
free(*tofree);
free(tofree);
free(m);
}

当我在第一次打印输出后在 valgrind 下运行程序时,我得到:

==6688== Memcheck, a memory error detector
==6688== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6688== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==6688== Command: ./e1
==6688==
Avvio Mat_alloc...

questa e' la riga: 0 con indirizzo: 4a4c4f0

0.000000 io sono l'elemento: 0 con indirizzo: 4a4c560
==6688== Invalid write of size 4
==6688== at 0x109311: Mat_alloc (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== by 0x1091FE: main (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== Address 0x4a4c564 is 0 bytes after a block of size 4 alloc'd
==6688== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==6688== by 0x1092BC: Mat_alloc (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== by 0x1091FE: main (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688==
==6688== Invalid read of size 4
==6688== at 0x109319: Mat_alloc (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== by 0x1091FE: main (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== Address 0x4a4c564 is 0 bytes after a block of size 4 alloc'd
==6688== at 0x483874F: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==6688== by 0x1092BC: Mat_alloc (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688== by 0x1091FE: main (in /home/sam/Scrivania/esercitazione 4 TDP/e1)
==6688==

但是我没有收到 sigsegv 信号,程序继续运行。我错了什么?我发现这更奇怪,因为释放不会产生任何错误,并且所有 block 都被释放。大家有什么建议吗?

她的主要功能:

int main(int argc, char **argv) {
/********************************************************
* TEST Mat_alloc/Mat_read *
********************************************************/
printf("Avvio Mat_alloc...\n\n");
Mat *m1 = Mat_alloc(5,5);
float** try = (*m1).row_ptrs;
printf("%f\n",**try);
printf("fatto alloc\n");
Mat_free(m1);
printf("fatto free\n");

return 0;
}

最佳答案

您应该为 mat 结构分配内存,因为您返回指向该结构的指针。

试试这个:

#include <stdlib.h>
#include <stdio.h>

typedef struct {
int rows;
int cols;
float **arr;
} Mat;

Mat* Mat_alloc(int rows, int cols){
// memory allocation for struct Mat
Mat* matrice = (Mat*)malloc(sizeof(Mat));
// memory allocation for a given number of rows of our two-dimensional array
matrice->arr = (float **)malloc(rows * sizeof(float *));
int i = 0; int j = 0;
// each row is a one-dimensional array, so we must allocate memory for each element
for (i = 0; i < rows; ++i)
matrice->arr[i] = (float *)malloc(cols * sizeof(float));

(*matrice).rows=rows;
(*matrice).cols=cols;

for(i=0;i<rows; ++i){
printf("questa e' la riga: %d con indirizzo: %p\n\n",i,&matrice->arr[i]);
for(j=0;j<cols; ++j){
matrice->arr[i][j] = j;
printf("%f io sono l'elemento: %d con indirizzo: %p \n",matrice->arr[i][j],j,&matrice->arr[i][j]);
}
printf("\n");
}
return matrice;
}

void Mat_free(Mat *m){
int i = 0;
for(i=0;i< m->rows; ++i) {
free(m->arr[i]);
}

free(m->arr);
free(m);
}

int main(int argc, char **argv) {
/********************************************************
* TEST Mat_alloc/Mat_read *
********************************************************/
printf("Avvio Mat_alloc...\n\n");
Mat *m1 = Mat_alloc(3,3);
printf("fatto alloc\n");
Mat_free(m1);
printf("fatto free\n");

return 0;
}

关于c - Valgrind 报告无效的读取(和写入),但程序保持执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56339358/

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