Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - [C]Lettura da file e scrittura su matrice allocata dinamicamente
Forum - C/C++ - [C]Lettura da file e scrittura su matrice allocata dinamicamente

Avatar
R_M (Normal User)
Newbie


Messaggi: 4
Iscritto: 07/02/2011

Segnala al moderatore
Postato alle 19:45
Mercoledì, 09/02/2011
Ho un file di interi e sò solo che il numero totale degli interi è dispari. Della sequenza del file devo leggere l'intero centrale (ad es. se ho 13 interi devo leggere il 7). Il valore di questo intero è la dimensione della matrice quadrata che devo allocare dinamicamente. Dopo averla allocata dinamicamente, la devo riempire con gli interi del file, tranne quello che mi ha dato la dimensione. Se gli interi del file sono di meno degli elementi che può contenere la matrice, allora quelli rimanenti gli inizializzo a zero.

Non ho errori in compilazione, ma in esecuzione. Mi dà errore di segmentazione nella riempi_matrice sulla fread al terzo giro del ciclo

Ecco il codice che ho scritto:

Codice sorgente - presumibilmente C++

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3.  
  4. void alloca_matrice(int***,int*,int*);
  5. void riempi_matrice(int***,int,int);
  6. void stampa(int**,int);
  7.  
  8. int main()
  9. {
  10.     int** matrice=NULL;
  11.     int dimensione=0;
  12.     int elementi=0;
  13.    
  14.     alloca_matrice(&matrice,&dimensione,&elementi);
  15.     riempi_matrice(&matrice,dimensione,elementi);
  16.     stampa(matrice,dimensione);
  17.     system("pause");
  18.     return 0;    
  19. }
  20.  
  21. void alloca_matrice(int***m,int*dim,int*num)
  22. {
  23.      FILE* fp=NULL;
  24.      int i;
  25.      int end=0;
  26.      fp=fopen("seq.dat","rb");
  27.      fseek(fp,0,SEEK_END);
  28.      end=ftell(fp);
  29.      fseek(fp,0,SEEK_SET);
  30.      while((ftell(fp))!=end)
  31.      {
  32.                             (*num)++;
  33.                             fseek(fp,sizeof(int),SEEK_CUR);
  34.                             printf("2");
  35.      }
  36.      *dim=((*num)/2);
  37.      fseek(fp,(*dim)*sizeof(int),SEEK_SET);
  38.      fread(dim,sizeof(int),1,fp);
  39.      if(((*dim)*(*dim))<(*num))
  40.      {
  41.          printf("Il file contiene più interi di quanti ne puo' contenere la matrice");
  42.          exit(1);
  43.      }
  44.      else
  45.      {    
  46.           *m=malloc((*dim)*sizeof(int));
  47.           for(i=0;i<(*dim);i++);
  48.           {
  49.                          (**m)[i]=malloc((*dim)*sizeof(int));
  50.           }
  51.       }    
  52.      fclose(fp);
  53.      printf("1");
  54.      printf("\nnum= %d", *num);
  55.      printf("\ndim= %d", *dim);
  56. }
  57.  
  58. void riempi_matrice(int*** m,int dim,int num)
  59. {
  60.      FILE*fp=NULL;
  61.      int i,j;
  62.      int flag=0;
  63.      fp=fopen("seq.dat","rb");
  64.      do
  65.      {
  66.           for(i=0;i<dim;i++)
  67.           {
  68.                     for(j=0;j<dim;j++)
  69.                     {
  70.                         if(flag==((num/2)+1))
  71.                         {}
  72.                         else
  73.                         {
  74.                             fread((&m)[i][j],sizeof(int),1,fp);
  75.                             flag++;
  76.                             printf("\n%d    %d      %d        %d",i,j,num,flag);
  77.                         }
  78.                     }
  79.           }    
  80.      }
  81.      while((i+j)<num);
  82.      for(;i<dim;i++)
  83.      {
  84.                     for(;j<dim;j++)
  85.                     {
  86.                         (*m)[i][j]=0;
  87.                     }
  88.      }        
  89.      fclose(fp);
  90.      printf("2");
  91. }
  92.  
  93. void stampa(int** m,int dim)
  94. {
  95.      int i,j;
  96.      for(i=0;i<dim;i++)
  97.      {
  98.                        for(j=0;j<dim;j++)
  99.                        {
  100.                                          printf("%d", m[i][j]);
  101.                        }
  102.                        printf("/n");
  103.      }
  104. }


PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Up
0
Down
V
Segnala al moderatore
Postato alle 10:36
Giovedì, 10/02/2011
Un triplo puntatore? LOL Credo sia la prima volta che ne vedo uno, il che mi fa meditare sulla vita, l'universo e tutto il resto.
Comunque, l'errore di segmentazione, secondo me, è quasi sicuramente dovuto al triplo puntatore, non perché tu non li sappia usare, ma perché è abbastanza arduo non perderne il controllo. Per questo ti consiglio di linearizzare la matrice, con cui è sufficiente un singolo puntatore.
Codice sorgente - presumibilmente VB.NET

  1. int* m;
  2. // m indica l'indirizzo del primo elemento della matrice
  3. m = (int*)malloc(sizeof(int) * dim * dim);
  4. // l'elemento (i, j) nella matrice si trova alla posizione i * dim + j dell'array m
  5. int item = *(m + i * dim + j); // oppure m[i * dim + j]
  6. // per ottenere l'indirizzo dell'elemento (i, j) puoi fare:
  7. int* addr = &(m[i * dim + j]); // oppure m + i * dim + j


Se vuoi passare la matrice per riferimento nella tua funzione, allora un puntatore doppio è sufficiente.

Per quanto riguarda il tuo codice:
Codice sorgente - presumibilmente Plain Text

  1. fread((&m)[ i ][j],sizeof(int),1,fp);


Se consideriamo m come un puntatore ad array di array, allora per passare l'indirizzo del j-esimo elemento dell'array i-esimo, se non sbaglio i conti, si fa in questo modo:
Codice sorgente - presumibilmente Plain Text

  1. fread(&((*m)[ i ][j]),sizeof(int),1,fp);


m è il puntatore al puntatore al primo elemento dell'array di array, quindi *m è il puntatore al primo elemento dell'array. Perciò (*m)[ i ], oppure ((*m) + i) indica l'i-esimo elemento dell'array, che è a sua volta un puntatore al primo elemento del secondo array. Risulta infine che (*m)[ i ][j] punta all'elemento j dell'array i-esimo. Perciò il suo indirizzo è &((*m)[ i ][j]).
O forse no... non mi sono mai piaciuti tanto i puntatori.

Ultima modifica effettuata da Il Totem il 10/02/2011 alle 10:40


"Infelici sono quelli che hanno tanto cervello da vedere la loro stupidità."
(Fligende Blatter)

"Dubitare di se stessi è il primo segno d'intelligenza."
(Ugo Ojetti)
PM