Я пытаюсь решить одну из моих тренировок для экзамена в университете, но у меня застряла ошибка памяти, которую я не могу понять.Я должен выделить и инициализировать матрицу типа float, имеющую в качестве матрицы структуру с именем 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, и программа продолжает работать.Что я делаю не так?Я нашел это даже более странным, потому что free не генерирует никаких ошибок, и все блоки free'd.Ребята, у вас есть предложения?
Ее главная функция:
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;
}