Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Come funziona un puntatore ad una struttura ?
Forum - C/C++ - Come funziona un puntatore ad una struttura ?

Avatar
mago85 (Normal User)
Newbie


Messaggi: 1
Iscritto: 06/10/2010

Segnala al moderatore
Postato alle 23:07
Mercoledì, 06/10/2010
Ciao a tutti, sono MaGo85 e sono nuovo del forum.

Ne approfitto subito per porvi una questione per me irrisolvibile.

Sto da poco affrontando l'annosa questione dei puntatori, con conseguente
allocazione di memoria ecc.
Ok, a questo aggiungiamoci le strutture e cosa ottengo ? Un po' di confusione...

Allora per testare le mie competenze, ho cercato di realizzare un semplice programmino che forniti dei dati in input, li memorizzi una struttura e poi stampi a video un resoconto del tutto.

Fatto ! Sembra funzionare tutto correttamente, ma al momento di stampare a video il resoconto, i valori che mi vengono stampati corrispondono tutti all'ultimo valore digitato...
Non riesco a capire cosa ci sia che non va

Vi riporto di seguito il codice

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5.  
  6. typedef struct option {
  7.         char *sedili;
  8.         char *volante;
  9. }optionals;
  10.  
  11. typedef struct car {
  12.         char *interni;
  13.         char *esterni;
  14.         char *cerchi;
  15.         optionals opt;
  16. }arg;
  17.  
  18. void inizializza(arg *macchina, int nmacchine);
  19. void inseriscidati(arg *macchina, int nmacchine);
  20. void stampadati(arg *macchina, int nmacchine);
  21.  
  22. int main(void){
  23.        
  24.         int macchine;
  25.         arg  * giulietta;
  26.        
  27.         printf("Inserisci il numero di Macchina da configurare: ");
  28.         scanf("%d", &macchine);
  29.         giulietta =(arg *) malloc(sizeof(arg)*macchine);
  30.         inizializza(giulietta, macchine);
  31.         inseriscidati(giulietta, macchine);
  32.         stampadati(giulietta, macchine);
  33.         free(giulietta);
  34.         return 0;
  35. }
  36.  
  37.  
  38.  
  39.  
  40. //Funzione per inizializzare la struttura con valori vuoti
  41. void inizializza(arg *macchina, int nmacchine){
  42.         int i=0;
  43.        
  44.         for (i=0;i<nmacchine;i++){
  45.                 (macchina+i)->interni = '\0';
  46.                 (macchina+i)->esterni = '\0';
  47.                 (macchina+i)->cerchi = '\0';
  48.                 (macchina+i)->opt.sedili = '\0';
  49.                 (macchina+i)->opt.volante = '\0';
  50.         }
  51. }
  52.  
  53. //Funzione per memorizzare i dati nella struttura
  54. void inseriscidati(arg *macchina, int nmacchine){
  55.        
  56.         int i=0;
  57.         char *temp;
  58.         for(i=0;i<nmacchine;i++){
  59.                 printf("\nMacchina %d:", i+1);
  60.                 temp = (char *) malloc(sizeof(char));
  61.                 printf("\nInserisci il tipo di interno: ");
  62.                 scanf("%s",temp);
  63.                 (macchina+i)->interni = temp;
  64.                 printf("\n%s", (macchina+i)->interni);
  65.                 printf("\nInserisci il colore degli esterni: ");
  66.                 scanf("%s",temp);
  67.                 (macchina+i)->esterni = temp;
  68.                 printf("\nInserisci il tipo di cherchi: ");
  69.                 scanf("%s",temp);
  70.                 (macchina+i)->cerchi = temp;
  71.                 printf("\nOPTIONALS:");
  72.                 printf("\nInserisci il colore dei sedili: ");
  73.                 scanf("%s",temp);
  74.                 (macchina+i)->opt.sedili = temp;
  75.                 printf("\nInserisci la tipologia di volante: ");
  76.                 scanf("%s",temp);
  77.                 (macchina+i)->opt.volante = temp;
  78.                 free(temp);
  79.         }
  80. }
  81.  
  82. //Funzione che stampa a video i dati della struttura
  83. void stampadati(arg *macchina, int nmacchine){
  84.         int i=0;
  85.         printf("\n\nCONFIGURAZIONI DISPONIBILI:");
  86.         for(i=0;i<nmacchine;i++){
  87.                 printf("\n\nGiulietta %d", i+1);
  88.                 printf("\nInterni: %s", (macchina+i)->interni);
  89.                 printf("\nEsterni: %s", (macchina+i)->esterni);
  90.                 printf("\nCerchi: %s", (macchina+i)->cerchi);
  91.                 printf("\nOPTIONALS");
  92.                 printf("\nInterni: %s", (macchina+i)->opt.sedili);
  93.                 printf("\nInterni: %s", (macchina+i)->opt.volante);
  94.         }
  95. }



Grazie per la pazienza se siete arrivati fino a qui...

PM
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Up
0
Down
V
Segnala al moderatore
Postato alle 12:21
Giovedì, 07/10/2010
Penso che il problema sia in inseriscidati. Tu usi una variabile temp (puntatore a carattere) allocandola dinamicamente ogni volta in un blocco da 1 byte. Non ha senso usare un puntatore a carattere per memorizzare un solo carattere. Se vuoi una stringa, devi allocare più spazio:
Codice sorgente - presumibilmente Plain Text

  1. temp = (char*)malloc(sizeof(char) * n);


n è una costante. Puoi usare sia gets che scanf.
Ma il problema è che fai la free di temp ad ogni iterazione. Questo significa che lo spazio puntato da interni, esterni, cerchi, sedili e volante è vuoto: nota che tutti i campi della struttura puntano alla stessa zona di memoria, perchè temp è stato allocato una sola volta e scanf cambia solo il valore dei dati in quell'indirizzo, ma non tocca l'indirizzo stesso.
Mi pare strano che non dia un segmentation fault...

PM
Avatar
Alex (Ex-Member)
Expert


Messaggi: 441
Iscritto: 15/08/2005

Up
0
Down
V
Segnala al moderatore
Postato alle 14:48
Venerdì, 08/10/2010
in inserisci dati hai allocato lo spazio per un char... forse non ti da errore perchè la scanf legge solo quel char e poi lascia i prossimi caratteri alla sua successiva chiamata perchè il vettore (che contiene solo un char) è pieno...

PM