|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
doppio array di puntatori
I need some help!!
Costruisco una matrice quadrata di puntatori allocando la memoria in questo modo (dove dim=dimensione asse x e anche asse y): float **matrix; matrix=(float **)malloc((dim*dim*sizeof(float))); for(m=0;m<dim;m++) { matrix[m] = (float *) malloc(dim*sizeof(float)); } Poi, questa matrice dovrei passarla ad un puntatore (float **matrix) in una struct chiamata LSU. Però, con questo comando: LSU[i].matrix=&matrix[0][0] che funziona bene con gli array unidimensionali, non riesco! Mi dà questo warning: assignment from incompatible pointer type. Qualcuno ha qualche suggeriemtno gentilmente?? |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
prima questione: perche' la prima allocazione e': Codice:
matrix=(float **)malloc((dim*dim*sizeof(float))); Oppure "gestisci la bidimensionalita'" tu, allocando un semplice array dim*dim e facendo matrix[riga * dim + colonna]. In secondo luogo, quando scrivi &matrix[0][0], ottieni semplicemente un puntatore ad un float (non un puntatore a puntatore a float), pertanto il warning visualizzato e' corretto. Domanda: invece di complicarti la vita, non e' possibile usare Codice:
LSU[i].matrix=matrix
__________________
In God we trust; all others bring data |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: May 2005
Città: Bari
Messaggi: 349
|
l'allocazione della matrice funziona in questa maniera:
-allochi un vettore colonna di puntatori; -con un ciclo for fai eseguire le malloc sul vettore colonna; quindi le istruzioni diventano: Codice:
#define DIM 5;
#include <stdio.h>
#include <stdlib.h>
void alloca_matrice(float **, int);
void main()
{
float **matrice;
alloca_matrice(matrice, DIM);
//A questo punto puoi creare una routine che assegni "matrice" (è già float **!!!) alla tua struct LSU
}
void alloca_matrice(float **matrix, int A)
{
int i;
matrix = malloc(A*sizeof(float *)); //Alloco il vettore colonna
for(i=0;i<A;i++) //Per ogni elemento del vettore alloco la riga
matrix[i] = malloc(A*sizeof(float));
}
Per ogni funzione alloca è opportuno definire una dealloca che operi in senso inverso, si intende. Puoi provare a giochicchiare ampliando lo stralcio di codice che ho scritto. Vito
__________________
Si può vincere una guerra in due...o forse anche da solo. Si può estrarre il cuore anche al più nero assassino, ma è più difficile cambiare un'idea! |
|
|
|
|
|
#4 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
non funziona
X SOTTOVENTO
...niente!! La malloc ora funziona, però quando si tratta di passare la matrice bidimensionale alla struct, non lo fa. La lettura del file è giusta e la matrice bidimensionale viene popolata correttamente. Però, non appena scrivo LSU.matrix[i]=matrix; poi nel doppio array di puntatori non riesce più a leggere i dati letti e non stampa più la matrice. |
|
|
|
|
|
#5 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
scusa, LSU[i].matrix.matrix. Ho sbagliato a scrivere....
Boh, non funziona... |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Mi viene un dubbio: come hai definito LSU[i].matrix.matrix?
E' un doppio puntatore a float? Oppure la tua intenzione e' quella di registrare riga x riga?
__________________
In God we trust; all others bring data |
|
|
|
|
|
#7 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
io ho una struct fatta così:
Codice:
struct LSU
{
int LSU_id;
int number_of_cluster;
int *cluster;
float **matrix;
};
Codice:
float **trans_matrix; trans_matrix=malloc(dim*sizeof(float*)); Poi voglio passare a matrix (nella struct) la matrice creata tramite il comando che mi hai suggerito tu: Codice:
LSU[i].matrix=trans_matrix |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: May 2005
Città: Bari
Messaggi: 349
|
hai dichiarato il vettore di struct nel main??
potresti postare il codice intero della parte? ciò che hai scritto mi sembra giusto! Vito
__________________
Si può vincere una guerra in due...o forse anche da solo. Si può estrarre il cuore anche al più nero assassino, ma è più difficile cambiare un'idea! |
|
|
|
|
|
#9 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
Codice:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float **trans_matrix;
struct LSU
{
int LSU_id; // numero sequenziale dell'LSU considerata
int number_of_cluster; // numero di cluster presenti nell'LSU considerata
int *cluster; // elenco di cluster effettivamente presenti nell'LSU considerata
float **matrix; // matrice delle transizioni
};
/*
* questo programma legge un file testo contenente la suddivisione in cluster del filmato,
* ponendo le varie voci in una struct chiamata 'cluster'
*/
int main(int argc, const char *argv[])
{
FILE *matrix;
if (argc!=2) // check if number of argument is correct
{
printf("\n Usage: ./read_LSU FILE_IN.view#LSUmat\n");
exit (1);
}
matrix=fopen(argv[1],"r"); // read file .txt which describes each shot
if (matrix==NULL){
printf("Error while opening file FILE_IN.view#LSUmat!\n");
exit(1);
}
struct LSU *array_LSU; // alla posizione i dell'array ci sarà una struct relativa ad un cluster
int number_of_LSU, ii=0, jj=0, kk, ll, mx;
int xx, yy;
int temp_num_cluster;
fscanf(matrix, "%d\n", &number_of_LSU);
array_LSU=malloc(number_of_LSU*sizeof(struct LSU));
while((fscanf(matrix, "%d", &(array_LSU[ii].LSU_id))) != EOF)
{
fscanf(matrix, "%d", &(array_LSU[ii].number_of_cluster));
int *array_cluster;
array_cluster=malloc(array_LSU[ii].number_of_cluster*sizeof(int));
for(kk=0; kk < array_LSU[ii].number_of_cluster; kk++)
fscanf(matrix, "%d",&array_cluster[kk]);
array_LSU[ii].cluster=&array_cluster[0];
temp_num_cluster = array_LSU[ii].number_of_cluster;
/***********************************************************************************
leggo la MATRICE DELLE TRANSIZIONI e trasferisco i dati nella struct
***********************************************************************************/
trans_matrix=malloc(temp_num_cluster*sizeof(float*));
for(mx=0;mx<temp_num_cluster;mx++)
trans_matrix[mx] = malloc(temp_num_cluster*sizeof(float));
for(yy=0; yy<temp_num_cluster; yy++)
{
for(xx=0; xx<temp_num_cluster; xx++)
{
fscanf(matrix, "%f", &trans_matrix[xx][yy]);
}
}
array_LSU[ii].matrix=trans_matrix;
ii++;
}
return 0;
}
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: May 2005
Città: Bari
Messaggi: 349
|
non ho letto attentamente il codice...ma la prima cosa che mi viene in mente di dirti è un consiglio: cambia il nome al file pointer...
Vito
__________________
Si può vincere una guerra in due...o forse anche da solo. Si può estrarre il cuore anche al più nero assassino, ma è più difficile cambiare un'idea! |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Suona davvero strano...
Prima di tutto, sei davvero sicuro che quella sia la linea "incriminata"? Se, per esempio, la commenti, riesci a compilare senza il warning in questione? Beh, per risolvere il warning potresti usare un cast, del tipo: array_LSU[ii].matrix=(float **)trans_matrix; Mi sa che questo fa sparire il warning. Pero' il problema e' capire il motivo di questo warning. Se lo facciamo sparire magari nascondiamo il problema, invece che risolverlo. Ho controllato il codice ed e' tutto OK. Purtroppo non ho il tempo di farlo girare. Mi sento pero' di darti un consiglio: verifica sempre, dopo la malloc() che la memoria sia stata allocata correttamente (se non lo e', il puntatore sara' a NULL). Metti un piccolo controllo, quanto meno con un messaggio di errore ed un exit() nel caso che la malloc() ritorni NULL, per evitare di perdere le ore a cercare un problema inesistente in caso di errore in allocazione.
__________________
In God we trust; all others bring data |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ciao,
mi sono preso un minuto di tempo ed ho compilato il tuo codice (usando Visual C++). Risultato: non mi compare il warning che hai riportato. In compenso il compilatore mi avverte che la malloc() ritorna un puntatore a void*, quindi devo fare il cast del valore ritornato al tipo di destinazione (cioe' float*, float** oppure LSU*). A parte questo, si compila tutto correttamente e senza altri warning Spero ti possa essere utile
__________________
In God we trust; all others bring data |
|
|
|
|
|
#13 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
Ti mando in allegato il file testo che dovrebbe leggere. Ho messo solo 2 matrici per renderlo + semplice.
Quando legge questo file, la matrice che uso come temporanea, riceve giusta nelle sue posizioni i numeri; poi, se provo a trasferire questa matriuce nel doppio array di puntatori e poi rifaccio stampare questo array, mi dà segmentation fault: Codice:
0.00 0.50 0.50 0.00 0.00 0.00 0.20 0.20 0.20 0.40 0.33 0.33 0.33 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 1.00 0.00 0.00 0.00 Segmentation fault Non so davvero + che fare. Perchè non è un problema di compilazione a questo punto......... |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ok, ci do' un'occhiata piu' tardi. Spero di esserti utile
__________________
In God we trust; all others bring data |
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
e´ di solito buona norma mettere qualche printf in giro per capire cosa sta succedendo. Io l´ho provato e funziona. Il file di input l´ho chiamato xxx.dat e ho aggiunto qualche printf. Per il resto non ho cambiato niente.
Codice:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
float **trans_matrix;
struct LSU
{
int LSU_id; // numero sequenziale dell'LSU considerata
int number_of_cluster; // numero di cluster presenti nell'LSU considerata
int *cluster; // elenco di cluster effettivamente presenti nell'LSU considerata
float **matrix; // matrice delle transizioni
};
/*
* questo programma legge un file testo contenente la suddivisione in cluster del filmato,
* ponendo le varie voci in una struct chiamata 'cluster'
*/
int main(int argc, const char *argv[])
{
FILE *matrix;
if (argc!=2) // check if number of argument is correct
{
printf("\n Usage: ./read_LSU FILE_IN.view#LSUmat\n");
exit (1);
}
matrix=fopen(argv[1],"r"); // read file .txt which describes each shot
if (matrix==NULL){
printf("Error while opening file FILE_IN.view#LSUmat!\n");
exit(1);
}
struct LSU *array_LSU; // alla posizione i dell'array ci sara una struct relativa ad un cluster
int number_of_LSU, ii=0, jj=0, kk, ll, mx;
int xx, yy;
int temp_num_cluster;
fscanf(matrix, "%d\n", &number_of_LSU);
printf( "%d\n", number_of_LSU );
array_LSU=malloc(number_of_LSU*sizeof(struct LSU));
while((fscanf(matrix, "%d", &(array_LSU[ii].LSU_id))) != EOF)
{
fscanf(matrix, "%d", &(array_LSU[ii].number_of_cluster));
printf( "array_LSU[%i].number_of_cluster: <%i>\n", ii, array_LSU[ii].number_of_cluster );
int *array_cluster;
array_cluster=malloc(array_LSU[ii].number_of_cluster*sizeof(int));
for(kk=0; kk < array_LSU[ii].number_of_cluster; kk++)
{
fscanf(matrix, "%d",&array_cluster[kk]);
printf( "array_cluster[%i]: <%i>\n", kk, array_cluster[kk] );
}
array_LSU[ii].cluster=&array_cluster[0];
temp_num_cluster = array_LSU[ii].number_of_cluster;
/***********************************************************************************
leggo la MATRICE DELLE TRANSIZIONI e trasferisco i dati nella struct
***********************************************************************************/
trans_matrix=malloc(temp_num_cluster*sizeof(float*));
for(mx=0;mx<temp_num_cluster;mx++)
trans_matrix[mx] = malloc(temp_num_cluster*sizeof(float));
for(yy=0; yy<temp_num_cluster; yy++)
{
for(xx=0; xx<temp_num_cluster; xx++)
{
fscanf(matrix, "%f", &trans_matrix[xx][yy]);
printf( "trans_matrix[%i][%i]: <%f>\n", xx, yy, trans_matrix[xx][yy] );
}
}
array_LSU[ii].matrix=trans_matrix;
ii++;
}
return 0;
}
Quote:
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Ho fatto qualche prova con Visual C++ (questo passa il convento
Ho ottenuto anch'io il crash, MA NON sull'assegnamento in questione, bensi' sulla fscanf()! Il debugger mi segnalava un errore strano, per cui ho cercato su msdn, trovando che si tratta di un bug (se cosi' possiamo chiamarlo): http://support.microsoft.com/kb/37507/en-us Non conoscendo l'ambiente in cui operi, non so se questo ti puo' essere utile. Ad ogni modo, il problema e' sparito seguendo le indicazioni di quell'articolo, cioe' semplicemente inizializzando la variabile float prima di usarla: Codice:
for(yy=0; yy<temp_num_cluster; yy++)
{
for(xx=0; xx<temp_num_cluster; xx++)
{
trans_matrix[xx][yy] = 0.0; // Solo questo
fscanf(matrix, "%f", &trans_matrix[xx][yy]);
}
}
Tieni presente che sul mio sistema l'errore era di manipolazione dei float, pertanto potresti aver bisogno, su altri sistemi, di linkare la libreria matematica (per es. su unix/linux, linkare con l'opzione -lm)
__________________
In God we trust; all others bring data |
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
faccio bene a non usare MAI la scanf
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
#18 |
|
Junior Member
Iscritto dal: Jul 2007
Messaggi: 28
|
RISOLTO!!!
Dopo aver castato con float* tutto funziona...sembra che nella struct ci sia tutto. Perciò problema risolto! Grazie a sottovento e a tutti quelli che si sono sbattuti. a presto |
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: May 2006
Città: Wursteland
Messaggi: 1749
|
Quote:
__________________
Nintendo WIII 4d Turbo Intercooler - Sestium X 666 99,312 GHz - 6.984 Ram Σ(9999) MHz - HDD SATA 97e^(10) bytes 93³ rpm - ATI biberon X900z ∞Mb - Win Eight SP (1 > yours) 16 Valve |
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
|
Quote:
Ma quel che e' peggio, e' che e' vero!
__________________
In God we trust; all others bring data |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:51.




















