Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] - Problema di allocazione della memoria

    Salve a tutti!

    Ho fatto un programmino Agenda, che è stato implementato come array di struct.

    Il programma è finito, ma il mio unico problema è che il prof. lo vuole con array di struct allocati dinamicamente.

    Se volessi inserire un nuovo contatto nell'agenda, come devo allocare la memoria?

    Cioè come faccio a capire come riallocare la memoria per aggiungere lo spazio necessario al nuovo contatto, senza perdere i dati precedentemente salvati nel mio array di struct?

    Da tre giorni ci lavoro ed ancora non ho trovato la soluzione...Cosa devo controllare?

    Vi ringrazio...

    Spero di essere stato chiaro...
    Vi allego anche il codice...

    Codice PHP:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>

    typedef struct
            
    {
              
    int ID;
              
    char Cognome[32];
              
    char Nome[32];
            } 
    Persona;

    void InserisciPersona *New , int *n);
    void stampaPersona *List , int n );

    int main()
    {
      
    Persona *Contatti;
      
    int start/* Num di contatti */
      
      
    start 0;
      
    Contatti NULL;

      
    InserisciContatti , &start );  
      
    stampaContatti start );

      
    system("PAUSE");
      return 
    0;
    }

    void InserisciPersona *New , int *)
    {
      
    int idim;
      
      
    dim=*n;
      
    /* Se è la prima volta che inserisco */
      
    if ( dim == 
      { 
        
    /* Aggiungo dim++ = 1 elemento */   
        
    dim++;
        
    /* Alloco lo spazio */
        
    New =(Persona*) malloc sizeof Persona ) );
        
    /* Per i che va da 0 a 1 */
        
    for(i=0i<dim i++)
        {
          
    /* Il primo id è 1 */
          
    New[i].ID=dim;       
          
    /* Prendo il nome ed il cognome */
          
    printf("Cognome: ");
          
    scanf("%s" , New[i].Cognome);
          
    printf("Nome: ");
          
    scanf("%s" , New[i].Nome);
        } 
        
    /* Restituisco al main la dimensione aggiornata */
        
    = &dim;
      }
      
    /* Se ci sono elementi nell'Array */
      
    else
      {
        
        
    /* Aggiungo un elemento ai presenti */
        
    dim = *n;
        
    dim++;
        
        
    /* Rialloco lo spazio aggiungendo dim = dim+1 elemento */ 
        
    New =(Persona*) realloc ( New , dim );
      
        for(
    i=0i<dim i++)
        {
          New[
    i].ID=dim;
          
    /* Prendo il nome ed il cognome */
          
    printf("Cognome: ");
          
    scanf("%s" , New[i].Cognome);
          
    printf("Nome: ");
          
    scanf("%s" , New[i].Nome);    
        }
      }
    }


    void stampaPersona *List , int n )
    {
      
    int i;   
      for(
    i=0i<i++)
      {
        
    printf("%s %s\n" , List[i].Cognome , List[i].Nome);
      }
      
    system("PAUSE");


  2. #2
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,031
    /* Restituisco al main la dimensione aggiornata */
    n = &dim;
    sei sicuro che così facendo restituisci al main la dimensione aggiornata? secondo me stai soltanto cambiando il contenuto del puntatore; non è così: *n=dim ?

    E poi a che ti serve riallocare? quel codice non inserirà mai più di un contatto... sarà sempre il primo contatto a essere inserito, dopodichè il codice termina la sua esecuzione... almeno così mi pare...

    e fra l'altro a me la Stampa non funziona...

  3. #3
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,031
    L'ho guardato meglio...

    codice:
    typedef struct
            {
              int ID;
              char Cognome[32];
              char Nome[32];
            } Persona;
    
    void Inserisci( Persona **New , int *n);
    void stampa( Persona *List , int n );
    
    int main(){
       Persona *Contatti;
       int start, choice;
       start = 0;
       Contatti = NULL;
    
    printf("Premi 1 per inserire\n"
           "Premi 2 per terminare\n?");
    scanf("%d", &choice);
    
    while(choice!=2){
       Inserisci(&Contatti, &start );
       stampa(Contatti, start );
       printf("?");
       scanf("%d",&choice);
    }
       system("PAUSE");
    return 0;
    }
    
    void Inserisci( Persona **New , int *n ){
       int i, dim;
       Persona *NewP;
      
       dim=*n;
       if (dim == 0){
          dim++;
          NewP=(Persona*)malloc(sizeof(Persona));
       }
       else{
          dim++;
          NewP=(Persona*)realloc(*New, dim);
       }
       NewP[dim].ID=dim;
       printf("Cognome: ");
       scanf("%s" , NewP[dim].Cognome);
       printf("Nome: ");
       scanf("%s" , NewP[dim].Nome);
       *n = dim;
       *New=NewP;
    }
    
    void stampa( Persona *List , int n ){
       int i;
    
       for(i=1; i<=n; i++)
          printf("%s %s\n" , List[i].Cognome , List[i].Nome);
    }
    Innanzitutto come detto sopra devi fare (*n=dim e non (n=&dim, altrimenti start rimaraà sempre a zero perchè non stavi cambiando il suo valore ma semplicemente stavi facendo puntare n a dim, e uscito dalla funzione start rimane tale e quale a quando è entrato.

    Poi il primo parametro di Inserisci dev'essere un puntatore a puntatore, ovvero deve puntare all'indirizzo di memoria del puntatore Contatti se vuoi poter modificare il suo indirizzo da NULL all'elemento che inserisci... e così per ogni volta che reallochi.

    Ho messo un while così puoi inserire più nominativi, altrimeti si eseguiva soltanto una volta.

  4. #4
    Sei stato davvero gentilissimo! Non avrei mai pensato al doppio puntatore!

  5. #5
    Codice PHP:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    #include <string.h>
    /* !
     *  La struttura Telefono è utilizzata per memorizzare il Numero Telefonico 
     *  del Contatto ed il tipo ( "Etichetta" ) di numero 
     */
    typedef struct unsigned int  ID/*!< Variabile intera senza segno di 
                                        * indentificazione univoca del numero telefonico */
                                        
                     
    char  NumTel[50]; /*!< Stringa contenente il numero telefonico*/
                     
                     
    char  Etichetta [50]; /*!< Stringa contenente la tipologia di
                                            * numero telefonico: "Casa" , "Ufficio" , "Fax" , etc...*/
                   
    Telefono


    /* 
       La struttura Persona utilizzata per allocare un nuovo Contatto  
    */               
    typedef struct unsigned int  ID
                     
    char  Cognome [50]; 
                     
    char  Nome [50];
                     
    Telefono Tel;
                     
    char Indirizzo[100];
                   } 
    Persona
                   
    void InserisciPersona **New , int *n);
    void stampaPersona *List , int n );

    int main(){
       
    Persona *Contatti;
       
    int startchoice;
       
    start 0;
       
    Contatti NULL;

    printf("Premi 1 per inserire\n"
           "Premi 2 per terminare\n?"
    );
    scanf("%d", &choice);

    while(
    choice!=2){
       
    Inserisci(&Contatti, &start );
       
    stampa(Contattistart );
       
    printf("?");
       
    scanf("%d",&choice);
    }
       
    free(Contatti);
       
    system("PAUSE");
    return 
    0;
    }

    void InserisciPersona **New , int *)
    int idim;
      
    Persona *NewP;
      
      
    dim=*n;
      
      if (
    dim == 0){
        
    dim++;
        
    NewP=(Persona*)malloc(sizeof(Persona));
      }
      else{
        
    dim++;
        
    NewP = (Persona*)realloc(*New, dim);
      }

      
    system("CLS"); 
      
      
    /* Inserimento dati... */
      
    printf "\nInserimento Persona\n" );
      
      
    NewP[dim].ID=dim;  
      
    /* ...stampo l'ID */
      
    printf("\nID: %d\n" NewP[dim].ID); 
      
    /* Inserimento Cognome del Contatto nella struttura di appoggio */
      
    printf("Cognome: ");
      
    scanf("%s" NewP[dim].Cognome );
      
    /* Inserimento Nome del Contatto nella struttura di appoggio */
      
    printf("Nome: ");
      
    scanf "%s" NewP[dim].Nome );
      
    /* Inserimento Numero Telefonico del Contatto nella struttura di appoggio */
      
    printf("Numero: ");
      
    scanf("%s" NewP[dim].Tel.NumTel );
      
    /* Inserimento Tipo di Numero Telefonico del Contatto nella struttura di appoggio */
      
    printf("Tipo Numero: ");
      
    scanf("%s" NewP[dim].Tel.Etichetta );

      
    /* Inserimento Indirizzo del Contatto nella struttura di appoggio */
      
    getchar();
      
    printf("Indirizzo: ");
      
    fgetsNewP[dim].Indirizzo 100 stdin );
      
      
       
    /* Restutuisco al main i valori aggiornati */
       
    *dim;
       *New=
    NewP;

      
    /* Stampo un messaggio di di avviso e termino la procedura */ 
      
    system("CLS");
      
    printf "\nContatto inserito\n" ); 
      
    system("PAUSE");
      
    system("CLS"); 

       
       return;
       
    }

    void stampa Persona *List , int n )
    int i,   /* Variabile di iterazione per i cicli */
          
    len/* Lunghezza effettiva del file "Contatti.txt" */

      
    system("CLS"); 
       
      
    printf("\n");
      
    printf("\t\t +-----------------------------+\n");
      
    printf("\t\t +       Stampa Contatti       + \n");
      
    printf("\t\t +-----------------------------+\n\n");
      
      
    printf(" --------------------------------------------------------------------------\n");
      
    printf("ID\tCognome\tNome\tTelefono\tTipo\tIndirizzo\n" );
      
    printf(" --------------------------------------------------------------------------\n");
     
      
    /* Se non c'è nessun contatto, ossia la lunghezza del file è "zero" */
      
    if ( == )
      {
         
    printf("     -> Nessun Contatto Presente <-\n");
      }
      
    /* Altrimenti stampa la lista di contatti */
      
    else
      {
        for(
    i=1i<=ni++)
        {
          
    printf("%d\t%s\t%s\t%s\t%s\t%s\n" , List[i].ID , List[i].Cognome , List[i].Nome 
                                         List[
    i].Tel.NumTel , List[i].Tel.Etichetta 
                                         List[
    i].Indirizzo);
        } 
      } 
      
    printf("\n -----------------------------------------------------------------------n\n");

      
    printf("\n\n");
      
      
    system("PAUSE");
      
    system("CLS");  
      return; 


    Mi sono complicato un pò la vita...ma non funziona!
    Mi fa inserire il primo contatto fino all'indirizzo, appena inserisco l'indirizzo, si impalla tutto!
    HELP MEEEEEEEEEEE!!!

  6. #6
    Una domandina stupida utilizzare una struttura ricorsiva anzichè un array di strutture non era più semplice?

  7. #7
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,031
    codice:
    /* Inserimento Indirizzo del Contatto nella struttura di appoggio */
    getchar();
    printf("Indirizzo: ");
    fgets( NewP[dim].Indirizzo , 100 , stdin );
    perchè fgets? serve per scrivere su file...

    codice:
    while ( (C=getchar() )!='\n')
       NewP[dim].Indirizzo=c;
    così inserisci l'indirizzo...
    Poi sinceramente non so cosa stai facendo perchè vedo che parli di un file Contatti.txt di cui io non vedo nè il classico puntatore FILE * nè le funzioni di scrittura su file.

  8. #8
    Utente di HTML.it L'avatar di Lak3d
    Registrato dal
    Aug 2006
    Messaggi
    1,031
    Originariamente inviato da Marcoski
    Una domandina stupida utilizzare una struttura ricorsiva anzichè un array di strutture non era più semplice?
    stessa cosa che volevo suggerirgli io... una lista concatenata avrebbe risolto tutto più velocemente... ma a quanto leggo è obbligato per motivi scolastici a svilupparlo in quel modo.

  9. #9
    perchè fgets? serve per scrivere su file...
    Perchè l'indirizzo non è una stringa...Via A. Manzoni n. 21 lo prendo con fgest, passandogli il mio array e come file lo standard input...

    Per il file contatti.txt lascia perdere... mi serivarà dopo per salvare il contenuto dell'array...
    ma se non funziona così, figuriamoci con i files...

    codice:
     while ( (C=getchar() )!='\n')
       NewP[dim].Indirizzo=c;
    Non funziona questo mi da errore: 94 prova.c incompatible types in assignment

    Chiedo un suggerimento: se dovesse farla voi implementata mediante array di struct, come fareste?

    Io ho sviluppato tutte le funzioni per array statico, allocato staticamente.

    Ma il mio prof vuole che sia implementata con array statico allocato dinamicamente...

    E' pazzo! :berto:

    Dopo lo vorrà implementato con le liste! che a mio avviso è più semplice!

    Grazie ancora!

  10. #10
    Codice PHP:
    typedef struct
            
    {
              
    int ID;
              
    char Cognome[32];
              
    char Nome[32];
            } 
    Persona;

    void InserisciPersona **New , int *n);
    void stampaPersona *List , int n );

    int main(){
       
    Persona *Contatti;
       
    int startchoice;
       
    start 0;
       
    Contatti NULL;

    printf("Premi 1 per inserire\n"
           "Premi 2 per terminare\n?"
    );
    scanf("%d", &choice);

    while(
    choice!=2){
       
    Inserisci(&Contatti, &start );
       
    stampa(Contattistart );
       
    printf("?");
       
    scanf("%d",&choice);
    }
       
    system("PAUSE");
    return 
    0;
    }

    void InserisciPersona **New , int *){
       
    int idim;
       
    Persona *NewP;
      
       
    dim=*n;
       if (
    dim == 0){
          
    dim++;
          
    NewP=(Persona*)malloc(sizeof(Persona));
       }
       else{
          
    dim++;
          
    NewP=(Persona*)realloc(*New, dim);
       }
       
    NewP[dim].ID=dim;
       
    printf("Cognome: ");
       
    scanf("%s" NewP[dim].Cognome);
       
    printf("Nome: ");
       
    scanf("%s" NewP[dim].Nome);
       *
    dim;
       *New=
    NewP;
    }

    void stampaPersona *List , int n ){
       
    int i;

       for(
    i=1i<=ni++)
          
    printf("%s %s\n" , List[i].Cognome , List[i].Nome);

    Non funziona! Se inserisco gli elementi, ok. Ma se poi voglio uscire dopo aver inserito gli elementi si blocca!

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 © 2025 vBulletin Solutions, Inc. All rights reserved.