|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
[C]Matrici trasposte
Sto facendo un programma in grado di stampare la trasposta di una matrice data in input. Viene effettuata un'allocazione dinamica per le righe e le colonne, tuttavia al momento dell'inserimento dei numeri, il programma viene terminato inaspettatamente:
Codice:
#include <stdio.h>
#include <stdlib.h>
void allocate_memory ( int **matrix, int row, int col);
void load_matrix ( int **matrix, int row, int col );
void make_transpose ( int **matrix, int **transpose, int row, int col);
void print_matrix ( int **matrix, int row, int col );
int main (void) {
int **matrix, **transpose; //Matrices
int row=0, column=0;
printf("How many rows for the matrix?\n");
scanf("%d", &row);
printf("How many columns for the matrix?\n");
scanf("%d", &column);
allocate_memory( matrix, row, column);
load_matrix( matrix, row, column);
make_transpose( matrix, transpose, row, column);
print_matrix( matrix, row, column);
print_matrix(transpose, row, column);
return 0;
}
void allocate_memory( int **matrix, int row, int col)
{
int r;
if ((matrix= calloc(row, sizeof(int *)))== NULL) //Memory rows allocation
{
printf("Row allocation error, QUIT");
exit(1);
}
else
{
for (r=0; r < row; r++) //Memory columns allocation
if ((matrix[r]= calloc(col, sizeof(int)))==NULL)
{
printf("Column allocation error, QUIT");
exit(1);
}
}
}
void load_matrix ( int **matrix, int row, int col )
{
int r, c;
for ( r=0; r < row; r++)
for ( c=0; c < col; c++)
{
printf("Insert element %d.%d: ", r, c);
scanf("%d", &matrix[r][c]);
}
}
void make_transpose ( int **matrix, int **transpose, int row, int col)
{
int r, c;
for ( r=0; r < row; r++)
for ( c = 0; c < col; c++)
transpose[r][c] = matrix[c][r];
}
void print_matrix ( int **matrix, int row, int col )
{
int r, c;
for ( r=0; r < row; r++)
{
for ( c =0; c < col; c++)
printf("%d\t", matrix[r][c]);
printf("\n");
}
}
L'allocazione mi pare sia corretta...
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2789
|
La matrice qui è indirizzata tramite un doppio puntatore, se vuoi allocarla in una funzione diversa devi passare l'indirizzo del doppio puntatore, altrimenti le modifiche effettuate su di esso non saranno visibili all'esterno (per via del passaggio di parametri per copia), quindi nella funzione lavorerai con un triplo puntatore.
Codice:
int **matrix;
allocaMatrice(&matrix);
...
void allocaMatrice(int ***mat){
*mat=(int**)calloc...
...
}
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
oppure più semplicemente invece di ritornare un int **
tipo: int** allocate_memory(int rows, int cols); poi non hai allocato nemmeno la trasposta (e mancano tutte le free) |
|
|
|
|
|
#4 | ||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quote:
Comunque si lo so che mancano un paio di cose, ma i dettagli li aggiungo quando il programma almeno termina l'esecuzione correttamente.
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Perchè se con due faccio così: Codice:
int r;
if ((matrix= calloc(row, sizeof(int *)))== NULL) //Memory rows allocation
{
printf("Row allocation error, QUIT");
exit(1);
}
else
{
for (r=0; r < row; r++) //Memory columns allocation
if ((matrix[r]= calloc(col, sizeof(int)))==NULL)
{
printf("Column allocation error, QUIT");
exit(1);
}
}
Codice:
int r;
if ((*matrix= calloc(row, sizeof(int **)))== NULL) //Memory rows allocation
{
printf("Row allocation error, QUIT");
exit(1);
}
else
{
for (r=0; r < row; r++) //Memory columns allocation
if ((*matrix[r]= calloc(col, sizeof(int *)))==NULL)
{
printf("Column allocation error, QUIT");
exit(1);
}
}
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Quote:
Codice:
int** allocaMatrice(int r, int c) {
int **matrix = malloc(sizeof(int*) * r);
if (matrix) {
int i;
for (i = 0; i < r; i++) {
matrix[i] = malloc(sizeof(int) * c);
if (!matrix[i]) {
int j;
for (j = 0; j < i; j++)
free(matrix[j]);
free(matrix);
return NULL;
}
}
}
return matrix;
}
int **matrix = allocaMatrice(r, c); e chiaramente controllare che non abbia ritornato NULL per gestire l'errore.. in pratica puoi riutilizzare la tua funzione, solo cambiare il valore di ritorno e togliere il parametro matrix che passi che risulta inutile inoltre nel codice che hai scritto Codice:
if ((*matrix= calloc(row, sizeof(int **)))== NULL) [...] if ((*matrix[r]= calloc(col, sizeof(int *)))==NULL) |
|
|
|
|
|
|
#7 | ||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Poi quando inserisci: Codice:
if(matrix) Codice:
if (!matrix[i]) { Ovviamente con ! fa il NOT, questo lo so } Per il resto, provo e ti faccio sapere. Quote:
EDIT: Ci sono riuscito!! Però non capisco questa parte di codice che hai scritto tu: Codice:
if (!matrix[i]) {
int j;
for (j = 0; j < i; j++)
free(matrix[j]);
free(matrix);
return NULL;
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
Ultima modifica di kwb : 16-08-2010 alle 09:23. |
||
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
metti caso che riesca ad allocare il vettore di int* (vale a dire le righe) e poi magari anche qualche colonna, ma poi malloc cominci a restituire NULL, devi deallocare tutto quello che hai allocato prima di restituire NULL, sennò hai un memory leak
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Dovresti allocare memoria anche per transpose, cosi' da evitare crash
__________________
In God we trust; all others bring data |
|
|
|
|
|
#10 | ||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Controllo Alloco Controllo Alloco ecc... Quote:
Per la deallocazione ho fatto così, è corretto? Non mi restituisce errori e il programma funziona correttamente, però non sono certo sia giusto perchè ho pensato si possa presentare lo stesso problema che avevo durante il tentativo di fare una funzione solo per l'allocazione: Il prototipo: Codice:
void deallocate_memory ( int **matrix, int **transpose, int row, int col); Codice:
deallocate_memory(matrix, transpose, row, column); Codice:
void deallocate_memory ( int **matrix, int **transpose, int row, int col)
{
int r;
for ( r=0; r < row; r++)
{
free(matrix[r]);
free(transpose[r]);
}
free(matrix);
free(transpose);
}
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
||
|
|
|
|
|
#11 | |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Quote:
Per il resto la tua deallocazione è corretta. |
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
E' corretta, ma non molto conveniente. Se infatti deallocassi una sola matrice alla volta, avresti un'implementazione piu' semplice (si lo so, e' un esempio e la semplicita' e' solo questione di due righe) e la potresti usare dappertutto, anche nel caso che nel tuo programma ci sia una terza matrice contenente la somma ed una quarta contenente la differenza, ed una quinta....
__________________
In God we trust; all others bring data |
|
|
|
|
|
#13 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Osservazione giustissima... Ho fatto inoltre caso al fatto che in quel modo c'è un errore nel caso in cui la matrice non sia quadrata, dato che le righe della matrice sono in realtà le colonne della trasposta, quindi non puoi operare nello stesso ciclo...
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Quote:
ps (!matrix[i]) equivale a (matrix[i] == 0) cioè a (matrix[i] == NULL) visto che NULL è definito come 0x0 |
|
|
|
|
|
|
#15 | |||||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quote:
Quote:
Quote:
Quote:
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|||||
|
|
|
|
|
#16 | |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Quote:
Codice:
void deallocate_memory ( int **matrix, int **transpose, int row, int col)
{
deallocate_matrix(matrix,row);
deallocate_matrix(transpose,col);
}
void deallocate_matrix(int **matrix, int row)
{
int r;
for ( r=0; r < row; r++)
{
free(matrix[r]);
}
free(matrix);
}
|
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Poi anche per la deallocazione era necessario fare una funzione generica così da poter invertire righe e colonne per la trasposta. Devo dire che sto esercizio è servito come il pane per capire bene come funzionano ste matrici allocate dinamicamente.
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 04:27.




















