PDA

Visualizza la versione completa : [C] Problema Funzione che usa una matrice dinamica


Nasio91
16-01-2017, 17:05
Salve a tutti, devo realizzare un programma che legga da file una matrice, e restituisca data una colonna l'indice di riga col numero pi� alto.
Il mio prof valuta molto bene l'uso di una matrice dinamica, per cui mi stavo esercitando nell'usarle.
detto questo il mio codice � formato da tre funzioni.
Il main
la funzione leggi(che legge la matrice da file)
e la funzione mat_dim(che crea una matrice dinamica una volta lette numero di colonne e righe)



[CODE]void mat_dim(int **mat, int *r, int *c)
{
printf("%d %d", *r, *c);
int i=0;
//int j;
mat=malloc(*r*sizeof(int*));


while(i<*r){


mat[i]=malloc(*c*sizeof(int));
i++;
}
}


void leggi(int **mat, int *r, int *c){


int i;
int j;
FILE *read;
if ((read=fopen("campionato.txt", "r"))==NULL){
printf("Impossibile aprire file 'Campionato.txt'\n");
}
else{
fscanf(read, "%d", &r);
fscanf(read, "%d", &c);
}
mat_dim(&r,&c);

//prova inserimento dati e stampa matrice


//lettura matrice da file
/*i=0;
j=0;
while(i<*r){
while(j<*c){
fscanf(read, "%d", &mat[i][j]);
j++;
}i++;
}*/
fclose(read);



}



Il codice e' sprovvisto di lettura di dati da file perche' appena termina la chiamata di funzione mat_dim, il programma crasha e non capisco il motivo, anche il semplice inserimento di dati all'interno della matrice causa un crash, ma questo non succede se l'inserimento dei dati e la stampa viene fatto all'interno della funzione mat_dim

boots
16-01-2017, 18:28
Prima di tutto non ho capito perch passi r e c come puntatori...visto che non li devi modificare passali per valore. Inoltre nel tuo codice chiami mat_dim con i soli r e c.
Altra cosa: nella mat_dim(int** mat, int* r, int* c) devi tener presente che mat locale quindi se nella leggi la chiami cos



int** m;
mat_dim(m, r, c);


m NON punter alla matrice che hai allocato nella funzione e se ci tenti di accedere andr in crash il programma. Se vuoi mantenere il tuo approccio devi fare cos:



void mat_dim(int ***mat, int r, int c)
{
printf("%d %d\n", r, c);
int i=0;
*mat = (int**)malloc(sizeof(int*) * r);


while(i<r){
(*mat)[i]=(int*)malloc(sizeof(int) * c);
i++;
}
}


e chiamarla cos;


int** m;
mat_dim(&m, r, c);


Per sarebbe tutto pi semplice se tu creassi la matrice nella funzione e restituissi il suo puntatore:


int** mat_dim(int r, int c)
{


int i=0;
int** mat = (int**)malloc(sizeof(int*) * r);


while(i<r){
mat[i]=(int*)malloc(sizeof(int) * c);
i++;
}
return mat;
}


e la assegni al puntatore


int** m;
m = mat_dim(r, c);

Nasio91
19-01-2017, 00:43
Grazie mille per la delucidazione, sono ancora poco pratico con i puntatori, una domanda se volessi usare in un'altra funzione la matrice dinamica appena definita in leggi, mi converrebbe passare il suo puntatore in questo modo giusto?


int main(void) {
int **mat;
int r=1;
int c=1;


mat=leggi_file(mat, &r, &c);

}






int **leggi_file(int **mat, int *r, int *c)
{

//legge file

//legge righe e colonne
fscanf(read, "%d", &(*cr));
fscanf(read, "%d", &(*rr));


mat=mat_dim(*r,*c)

/*qui mi avevi consigliato questo mat=mat_dim(r,c) c' un concetto che non
mi ancora chiarissimo una volta passato l'indirizzo di memoria come parametro
ad una funzione, il rispettivo puntatore come va usato? passandoli nel modo da te consigliato
una volta che cerco di stamparne il valore nel main il programma va in crash*/

//leggi dati di mat da file


return mat;

}

boots
19-01-2017, 11:19
Allora, si dovrebbero passare oggetti per indirizzo (puntatore) quando o il parametro e un puntatore stesso oppure se hai intenzione di modificare l'oggetto passato nella funzione. Passare &r e &c nel tuo main corretto perch dopo che avrai eseguito la leggi_file le variabile r e c (del main) avranno il valore voluto. Visto che **mat definito nel mail ha senso che in quella funzione tu abbia oltre alla matrice anche la dimensione.
Non ha senso passarli alla mat_dim, perch r e c non li vai a modificare e quindi puoi passarli tranquillamente per valore (anche se nessuno ti vieta di passarli per indirizzo)

Inoltre inutile passare mat come parametro, visto che sar il valore di ritorno delle funzioni. Quindi puoi fare una cosa del genere:



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

// Ti crea la matrice e ti restituisce il puntatore
// Gli basta sapere la dimensione
int** mat_dim(int r, int c)
{
int i=0;
int** mat = (int**)malloc(sizeof(int*) * r);
while(i<r){
mat[i]=(int*)malloc(sizeof(int) * c);
i++;
}
return mat;
}

// Visto righe e colonne vengono assegnati qui, li vogliamo "far tornare indietro" (r e c) e quindi li prendiamo per indirizzo
int **leggi_file(int *r, int *c)
{
int i, j;
//legge righe e colonne
printf("Numero di righe:");
scanf("%d", &(*r));
printf("\nNumero di colonne:");
scanf("%d", &(*c));
// *r e *c puntano alle variabili del main!!!
// Quindi avranno il valore letto

// Chiamo la funzione che crea la matrice, passandogli la dimensione (valore di r e c)
// e assegnamo il valore di ritorno alla variabile mat
int** mat=mat_dim(*r,*c);

//leggi dati di mat da file ... io li metto a 2
for(i=0; i<*r;i++)
for(j=0; j<*c;j++)
mat[i][j] = 2;
// Restituiamo il puntatore
return mat;
}

// Funzione che ti stampa ma matrice
// Come vedi prende come parametro il puntatore e la dimensione
void print_m(int** mat, int r, int c){
for(int i=0; i<r;i++){
for(int j=0; j<c;j++)
printf("%d ", mat[i][j]);
printf("\n");
}
}

int main(void) {
int **mat;
int r=1;
int c=1;

mat=leggi_file(&r, &c);
// Alla fine della storia mat punter alla zona allocata per la matrice ed r e c conterranno la dimensione
printf("dimensione matrice %d %d\n", r, c);
printf("Matrice\n");
print_m(mat, r, c);
return 0;
}

Nasio91
21-01-2017, 12:19
Grazie mille! Sei stato molto esaustivo!

Loading