Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C]: allocazione dinamica matrice

    Salve a tutti! Stavo facendo delle prove per allocare e reallocare dinamicamente una matrice... ma se eseguo il codice mi si blocca tutto.
    Qualcuno saprebbe spiegarmi perchè?
    Sicuramente sbaglio qualcosa, ma non riesco a trovare la soluzione...

    Questo è il codice:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    double** allocaMatrice(int righe, int colonne);
    double** reAllocaMatrice(double **mat, int righe, int colonne);
    void riempiMatrice(double **mat, int *righe, int *colonne);
    void usaMatrice(double **mat, int righe, int colonne);
    
    
    void main(){
    	double **mat;
    	int i;
    	int righe = 2;
    	int colonne = 2;
    
    	mat = allocaMatrice(righe, colonne);
    
    	riempiMatrice(mat, &righe, &colonne);
    	usaMatrice(mat, righe, colonne);
    	
    
    	//dealloco matrice
    	for(i=0; i<colonne; i++){
    		free(mat[i]);
    	}
    	free(mat);
    }
    
    double** allocaMatrice(int righe, int colonne){
    	int i;
    	double **mat;
    
    	mat = (double**)malloc(righe*(sizeof(double*)));
    	if (mat == NULL){
    		puts("Spazio insufficiente");
    		exit(0);
    	}
    
    	for (i=0; i<righe; i++){
    		mat[i] = (double*)malloc(colonne*sizeof(double));
    		if (mat[i] == NULL){
    			puts("Spazio insufficiente");
    			exit(0);
    		}
    	}	
    	
    	return mat;
    }
    
    double** reAllocaMatrice(double **mat, int righe, int colonne){
    	int i;
    
    	mat = (double**)realloc(mat, sizeof(double*)*righe);
    	if (mat == NULL){
    		puts("Spazio insufficiente");
    		exit(0);
    	}
    
    	for (i=0; i<righe; i++){
    		mat[i] = (double*)realloc(mat, sizeof(double)*colonne);
    		if (mat[i] == NULL){
    			puts("Spazio insufficiente");
    			exit(0);
    		}
    	}	
    	
    	return mat;
    }
    
    void riempiMatrice(double **mat, int *righe, int *colonne){
    	int i, j;
    	*righe = 5;
    	*colonne = 6;
    	
    	mat = reAllocaMatrice(mat, *righe, *colonne);
    
    	for(i=0; i<*righe; i++){
    		for(j=0; j<*colonne; j++){
    			mat[i][j] = 0.0;
    		}
    	}
    }
    
    void usaMatrice(double **mat, int righe, int colonne){
    	int i, j;
    
    	for(i=0; i<righe; i++){
    		printf("\n");
    		for(j=0; j<colonne; j++){
    			printf("%d ", mat[i][j]);
    		}
    	}
    }

  2. #2
    È sbagliato il concetto che una matrice a più indici sia una matrice di puntatori che puntano alle singole righe.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    grazie per la risposta, ma non capisco perchè dovrebbe essere sbagliato...
    ho cercato un pò e ho visto che per allocare dinamicamente una matrice si fa così, inoltre questo codice funziona:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    double** allocaMatrice(int righe, int colonne);
    
    void main(){
    	double **mat;
    	int i, j;
    	int righe = 2;
    	int colonne = 2;
    
    	mat = allocaMatrice(righe, colonne);
    
    	for(i=0; i<righe; i++){
    		for(j=0; j<colonne; j++){
    			mat[i][j] = 0.0;
    		}
    	}
    	
    	for(i=0; i<righe; i++){
    		printf("\n");
    		for(j=0; j<colonne; j++){
    			printf("%d", mat[i][j]);
    		}
    	}
    
    	//dealloco matrice
    	for(i=0; i<colonne; i++){
    		free(mat[i]);
    	}
    	free(mat);
    }
    
    
    double** allocaMatrice(int righe, int colonne){
    	int i;
    	double **mat;
    
    	mat = (double**)calloc(righe,sizeof(double*));
    	if (mat == NULL){
    		puts("Spazio insufficiente");
    		exit(0);
    	}
    
    	for (i=0; i<righe; i++){
    		mat[i] = (double*)calloc(colonne,sizeof(double));
    		if (mat[i] == NULL){
    			puts("Spazio insufficiente");
    			exit(0);
    		}
    	}	
    	
    	return mat;
    }
    il problema nasce quando cerco di reallocare la matrice...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254

    Re: [C]: allocazione dinamica matrice

    Originariamente inviato da pixellosa
    codice:
    double** reAllocaMatrice(double **mat, int righe, int colonne){
    	int i;
    
    	mat = (double**)realloc(mat, sizeof(double*)*righe);
    	if (mat == NULL){
    		puts("Spazio insufficiente");
    		exit(0);
    	}
    
    	for (i=0; i<righe; i++){
    		mat[i] = (double*)realloc(mat, sizeof(double)*colonne);
    		if (mat[i] == NULL){
    			puts("Spazio insufficiente");
    			exit(0);
    		}
    	}	
    	
    	return mat;
    }
    Intanto posso assicurarti che il concetto dell'utilizzo di un array di puntatori che puntano ad altri array per gestire un array bidimensionali è giusto. Avevo già spiegato la questione in <questo> thread.

    Comunque l'errore l'ho segnato in rosso. Guarda cosa hai cercato di riallocare nella seconda realloc.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    grazie per l'aiuto, non me ne ero accorta... comunque deve essere così? non ne sono sicura, perchè ancora non mi funziona...

    codice:
    double** reAllocaMatrice(double **mat, int righe, int colonne){
    	int i;
    
    	mat = (double**)realloc(mat, sizeof(double*)*righe);
    	if (mat == NULL){
    		puts("Spazio insufficiente");
    		exit(0);
    	}
    
    	for (i=0; i<righe; i++){
    		mat[i] = (double*)realloc(mat[i], sizeof(double)*colonne);
    		if (mat[i] == NULL){
    			puts("Spazio insufficiente");
    			exit(0);
    		}
    	}	
    	
    	return mat;
    }

  6. #6
    Credo che il problema sia dovuto al valore che passi alla seconda realloc (quella segnata in rosso nelle mail precedenti) e che hai corrento con realloc(mat[i], ....). Non vorrei sbagliarmi ma la realloc richiede che il puntatore che gli passi (in questo caso mat[i]) sia NULL o un puntatore ottenuto da una prima chiamata a malloc/calloc. In questo caso dato che fai una realloc(mat), i valori di mat[i] nuovi (cioè quelli ottenuti dall'espansione di mat) sono rumenta e quindi la realloc probabilmente si arrabbia (però non so' se la realloc inizializza la memoria a zero come la calloc, ma non credo).
    Quindi dopo la realloc di mat, inizializzerei la nuova memoria (quella espansa dalla realloc) a NULL.
    E' solo un'ipotesi comunque

  7. #7

    Re: Re: [C]: allocazione dinamica matrice

    Originariamente inviato da andbin
    Intanto posso assicurarti che il concetto dell'utilizzo di un array di puntatori che puntano ad altri array per gestire un array bidimensionali è giusto. Avevo già spiegato la questione in <questo> thread.
    Chiedo scusa; sono abituato ad allocare "veri array" con l'ottima keyword new senza ricorrere ad array di puntatori, metodo che mi riesce spesso più comodo.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Originariamente inviato da pixellosa
    grazie per l'aiuto, non me ne ero accorta... comunque deve essere così? non ne sono sicura, perchè ancora non mi funziona...
    Il problema è che se aumenti il numero delle righe, lo spazio per i puntatori aggiuntivi riallocato dalla prima realloc non è inizializzato.
    Prima di fare il ciclo for delle righe, dovresti azzerare i puntatori "nuovi". In questo modo se mat[i] vale NULL, la realloc si comporta come una malloc.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  9. #9
    Avevate ragione, è bastato aggiungere
    codice:
    	
    for (i=0; i<righe; i++){
    	mat[i] = NULL;
    }
    prima di reallocare le colonne funziona! Si imparano sempre cose nuove...

    Però è sorto un altro problema.... strano.... ora non mi dealloca più la matrice.
    Commentando il codice relativo alla deallocazione tutto funziona, ma se voglio deallocare mi si impianta...
    Spero sappiate aiutarmi anche in questo.

  10. #10
    Se il ciclo lo fai così stai perdendo memoria perchè metti a NULL anche i precendenti puntatori che invece dovresti deallocare e poi liberare. Il problema è che non mantieni il vecchio numero di righe, dovresti ternertelo e fare il ciclo così:
    codice:
    for (i=old_righe; i<righe; i++){
    	mat[i] = NULL;
    }
    Poi per il problema della deallocazione credo che il ciclo dovrebbe essere fatto sul numero di righe e non di colonne.
    codice:
    	//dealloco matrice
    	for(i=0; i<righe; i++){
    		free(mat[i]);
    	}
    	free(mat);

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.