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

    chiarimento utilizzo malloc

    Ciao, in questo codice utilizzo la funzione malloc al di fuori del ciclo "do while", ciò vuol dire che mi alloca la memoria necessaria solo al primo elemento dell'array (giacchè nel sizeof non ho specificato "n*" è come se avessi scritto 1*).
    Solo così il programmino riesce a girare; secondo me invece dovrei allocare 1 elemento per ogni volta che scelgo di inserire un nuovo dato. Se, però inserisco la malloc all'interno del "do while" il programma non gira.
    Mi sa che così, anche se funziona tutto, gestisco male la memoria.
    Qualcuno potrebbe chiarirmi le idee?
    grazie in anticipo
    codice:
    struct mail{
                char indirizzo[30];
            } *email = NULL;
            int i=-1; 
            int n=0;
            char scelta[2];
            email=(struct mail*)malloc(sizeof(struct mail));
            do {
                i++;
                printf("\nInserisci il %d° indirizzo email: ",i+1);
                scanf("%s", email[i].indirizzo);
                printf("\nNuovo indirizzo?: ");
                scanf("%s", scelta);
            } while (strcmp(scelta,"s")==0);
            for (n=0; n<=i; n++) {
                printf("\nMail nr.%d: %s",n+1,email[n].indirizzo);
            }
            free (email);

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Certo che dovresti allocare nel ciclo ma dovresti avere anche un array di puntatori e non un semplice puntatore.

    Ovvero, ad esempio, per 100 inserimenti

    struct mail *email[100];

    nel ciclo

    email[i]=(struct mail *)malloc(sizeof(struct mail));

    e di conseguenza puntare all'elemento con il ->

    email[i]->indirizzo
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Potresti chiedere come ulteriore parametro N quanti indirizzi si vogliono inserire ed allocare la memoria in conseguenza di questo, in questo modo il ciclo avrebbe solo N interazione e non dovresti chiedere se si desidera inserirne altri.
    Oppure dovresti utilizzare realloc nel ciclo, questo manterrebbe la possibilità di inserire indirizzi finché l'utente dice stop ma non è il top dell'efficienza e bisogna riallocare con parsimonia (tipo ogni tot cicli).

    Approccio 2
    codice:
    # define NEW_RECORDS 10
    struct mail{
                char indirizzo[30];
            } *email = NULL;
            int i=-1; 
            int n=0;
            int allocazioni = 1;
            char scelta[2];
            email=(struct mail*)malloc(NEW_RECORDS*sizeof(struct mail)); //alloco inizialmente 10 posti
            do {
                i++;
                if (i == allocazioni * NEW_RECORDS){
                       email=(struct mail*)realloc(((allocazioni ++) * NEW_RECORDS)*sizeof(struct mail)); // realloc è dispendiosa, alloco 10 nuovi record per volta
                }
                printf("\nInserisci il %d° indirizzo email: ",i+1);
                scanf("%s", email[i].indirizzo);
                printf("\nNuovo indirizzo?: ");
                scanf("%s", scelta);
            } while (strcmp(scelta,"s")==0);
            for (n=0; n<=i; n++) {
                printf("\nMail nr.%d: %s",n+1,email[n].indirizzo);
            }
            free (email);
    ...

  4. #4
    Utente bannato
    Registrato dal
    Apr 2012
    Messaggi
    510

    Re: chiarimento utilizzo malloc

    Considera questo codice:
    codice:
    struct mail{
                char indirizzo[30];
            } *email = NULL;
            int i=-1; 
            int n=0;
            char scelta[2];
            do {
                email=(struct mail*)malloc(sizeof(struct mail));
                i++;
                printf("\nInserisci il %d° indirizzo email: ",i+1);
                scanf("%s", email[i].indirizzo);
                printf("\nNuovo indirizzo?: ");
                scanf("%s", scelta);
            } while (strcmp(scelta,"s")==0);
            for (n=0; n<=i; n++) {
                printf("\nMail nr.%d: %s",n+1,email[n].indirizzo);
            }
            free (email);
    L' istruzione email=(struct mail*)malloc(sizeof(struct mail)); è un assegnamento.Ciò significa che se metti questa istruzione nel ciclo, continui a riassegnare il valore di email, che punterà alla nuova zona di memoria allocata.
    email non è un array, e tu nel for lo stai trattando come se fosse un array.
    Stampare email[0].indirizzo va bene, sarebbe come stampare (*email).indirizzo, cioè email->indirizzo, ma stampare email[1].indirizzo dovrebbe causare segmentation fault.
    oltre al segmentation fault c'è una perdita di memoria perché continui a riassegnare email senza liberare la zona di memoria precedentemente allocata.

  5. #5
    Grazie ragazzi, ho adottato la soluzione della realloc perché è più vicina alle mie esigenze; le altre prevedono un numero di inserimenti predefiniti e a me non piace.

    Capito anche il problema malloc all'interno del ciclo (in effetti era logico), però email lo tratto come se fosse un array perché voglio che sia un array di struct mail e credo di esserci riuscito perché mi stampa in ordine tutti gli indirizzi che vado ad inserire

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Non so che codice hai usato ma se non hai utilizzato un vettore di puntatori ma tratti il semplice puntatore come se lo fosse, il tuo programma potrà avere problemi di crash (che magari adesso non si verificano per motivi di status attuale della memoria).

    Ti consiglio di valutare bene quello che ti è stato suggerito, non perché sono delle soluzioni tra cui scegliere rispetto alla tua ma perché il tuo codice è sbagliato.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Il codice che ho usato è questo:

    codice:
    #define dim 5          //alloco 5 blocchi di memoria per volta(*allocazioni che viene incrementato ogni 5 inserimenti)
            struct mail{
                char indirizzo[30];
            } *email = NULL;
            int i=-1; 
            int n=0;
            int allocazioni=1;    //coefficiente per incrementare i blocchi da reallocare
            int alloc=1;          //dimensione nuovo blocco
            char scelta[2];
            email=(struct mail*)malloc(dim*sizeof(struct mail));
            do {
                i++;
                if (i == allocazioni * dim){   //quando i(num mail) diventa uguale ad un multiplo di 5
                    allocazioni++;  //aggiorno il coefficiente
                    alloc=allocazioni*dim; //definisco il nuovo blocco
                    email=(struct mail*)realloc(email, (alloc*sizeof(struct mail )));  //e rialloco la memoria
                }
                printf("\nInserisci il %d° indirizzo email: ",i+1);
                scanf("%s", email[i].indirizzo);
                printf("\nNuovo indirizzo?: ");
                scanf("%s", scelta);
            } while (strcmp(scelta,"s")==0);
            for (n=0; n<=i; n++) {
                printf("\nMail nr.%d: %s",n+1,email[n].indirizzo);
            }
            free (email);
    Se mi dite che sbaglio non c'è dubbio, mi fido ciecamente dell'esperienza ( altrimenti non stavo qui a scrivere), ma non riesco a capire dove:

    Ho letto (e spero di aver letto bene) che un vettore di caratteri statico (con il valore di "n" noto) lo dichiaro

    char xxx[n];

    mentre un vettore di caratteri dinamico lo dichiaro

    char *xxx;

    perché un vettore di struct dovrebbe essere diverso?

    D'altronde il fatto che quando stampo "email[n]" vengono mostrati i valori inseriti, correttamente ed in ordine di inserimento, mi fa supporre che per ogni valore di "n" è stata creata una cella (email[n]) che contiene l'ennesimo dato inserito.

    Fatemi capire dove sbaglio altrimenti comincio male

  8. #8
    Utente di HTML.it L'avatar di torn24
    Registrato dal
    Aug 2008
    Messaggi
    551

    ciao

    Non è sbagliato l'ultimo codice che hai inserito , e fa correttamente quello che ti serve!

    E' SBAGLIATA , la domanda che hai posto , hai chiesto ,in pratica ,se era possibile usare malloc all'interno del ciclo , quindi ti hanno risposto SI se usi un array di puntatori , e allochi per ogni elemento spazio per la struttura.
    ma non era quello che volevi fare tu, quindi , sono risposte che non ti servono e
    che "non devi prendere in considerazione" per questo problebla.

    La domanda che avresti dovuto porre è , come alloco altra memoria ad un array dinamico
    all'interno di un ciclo , e ti avrebbero indicato quasi sicuramente direttamente la realloc


    gli esperti non capiscono e non parlano il "principiantese"

    quindi noi ,che lo siamo ,dobbiamo spiegarci in modo corretto , altrimenti non otteniamo
    l'aiuto voluto
    Tecnologia

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da ipspaolo
    Il codice che ho usato è questo:
    Ti faccio notare che nel primo tuo post hai scritto

    email=(struct mail*)malloc(sizeof(struct mail));

    mentre nell'ultimo hai scritto

    email=(struct mail*)malloc(dim*sizeof(struct mail));

    Ovviamente sono cose diverse e solo la seconda è corretta.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Si, è vero, l'ho cambiato quando mi è stato suggerito di usare la realloc. A quel punto ho dovuto per forza allocare blocchi di misura" dim".
    Ragazzi/e vi ringrazio tutti e cosa importantissima è che grazie alle vostre indicazioni ho capito di avere capito

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