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

    [C] FREE su singola cella di vettore dinamico di strutture.

    Ciao, ho scritto queste righe di codice ma non fanno quello che avevo in mente.

    codice:
        // FUNZIONE CANCELLA //
        int tmp_matricola;
    
        printf("Numero di matricola dello studente che vuoi cancellare dall'archivio: ");
        scanf("%d", &tmp_matricola);
        for(i = 0; i < MAX_STUD; i++) {
            if(ptrVettStud[i].matricola == tmp_matricola) {
                free(ptrVettStud);
                printf("Operazione avvenuta con successo!\n");
                printf("Lo studente %s %s e' stato rimosso dall'archivio.\n", ptrVettStud[i].nome, ptrVettStud[i].cognome);
            }
            else {
                printf("Il numero di matricola non e' in elenco.\n");
            }
            break;
        }    
        printf("%d\n", ptrVettStud[0].matricola);
        printf("%d\n", ptrVettStud[1].matricola);
        printf("%d\n", ptrVettStud[2].matricola);

    Ci sono(almeno) due cose che non vanno: quando stampa nome e cognome dello studente cancellato il nome lo traduce in numero, sempre il solito, un 5.
    Seconda cosa, non riesco a fare la FREE sulla singola cella del vettore. I tre printf finali di verifica, nel caso inserissi tre nuove matricole, continuano a stampare anche quella eventualmente cancellata.
    In partenza ho scritto "free(ptrVettStud[i])" ma lo segnala come incompatibile.
    Questo sotto invece è come ho creato e allocato il vettore di strutture:

    codice:
    typedef struct{
        char nome[50];
        char cognome[50];
        int matricola;
        int voto[NUM_MAT];
    } STUDENTE;
    STUDENTE *ptrVettStud;
    
    ...
    
    for(i = 0; i < MAX_STUD; i++) {
            ptrVettStud = (STUDENTE*) malloc(sizeof(STUDENTE));
    }

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Sicuramente l'allocazione è sbagliata ... un vettori di elementi lo allochi con
    ptrVettStud = (STUDENTE*) malloc(MAX_STUD * sizeof(STUDENTE));

    e così facendo non puoi liberare un singolo elemento.


    Altrimenti dovresti usare un vettore di puntatori a struttura, quindi

    STUDENTE *ptrVettStud[MAX_STUD];

    e poi la for

    for(i = 0; i < MAX_STUD; i++)
    ptrVettStud[i] = (STUDENTE*) malloc(sizeof(STUDENTE));

    che forse è quello che volevi fare.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Si è quello che volevo fare e fatto inizialmente, poi ho perso il filo.
    Anche il problema del nome... inserito prima della free non da problemi.
    Quello che non capisco è se la free funziona, perché le stampe finali continuano a trovarmi i valori della matrice a quell'indice. Adesso il codice è questo, cioè con l'inserimento del secondo indice tipo matrice dopo la modifica della malloc come suggerita:

    codice:
    for(i = 0; i <= numeroInserimenti; i++) {
            if(ptrVettStud[i][0].matricola == tmp_matricola) {
                printf("Lo studente %s %s e' stato rimosso dall'archivio.\n", ptrVettStud[i][0].nome, ptrVettStud[i][0].cognome);
                free(ptrVettStud[i]);
                printf("Operazione avvenuta con successo!\n");
                printf("Lo studente %s %s e' stato rimosso dall'archivio.\n", ptrVettStud[i][0].nome, ptrVettStud[i][0].cognome);
            }
            else {
                printf("Il numero di matricola non e' in elenco.\n");
            }
            //break;
        }    
        
        printf("%d\n", ptrVettStud[0][0].matricola);
        printf("%d\n", ptrVettStud[1][0].matricola);
        printf("%d\n", ptrVettStud[2][0].matricola);

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    La free del C "segna" soltanto che l'area è libera e disponibile per altre allocazioni ma non cancella il suo contenuto. Se non sono intervenute altre allocazioni potresti tranquillamente accedere al vecchio contenuto.

    Forse ti aspetti che la free faccia qualcosa che in effetti non fa ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Infatti mi aspettavo che cancellasse proprio il contenuto. Mi vengono troppi dubbi, partiamo da capo: con la malloc corretta, ho fatto questo?

    malloc.jpg

  6. #6
    Quando mi si chiede di cancellare un record da un vettore di strutture allora, cosa si chiede di fare in realtà, una free su quell'indice o riportare quei valori a zero?

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Solamente questo

    free(ptrVettStud[i]);
    ptrVettStud[i]=NULL;

    così che il programma sappia che il puntatore a NULL indica che la struttura non è più disponibile.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Grazie, allora avevo fatto bene, ma senza impostare a null.
    Pensavo una cosa: potrebbe essere una buona soluzione impostare tutto il vettore a NULL al momento dell'allocazione, per usare il NULL come termine di confronto per scorrerlo fino alla prima posizione libera(NULL, appunto), e li inserire il nuovo record?

    Mi resta però un dubbio sulla sulla FREE: come controllo la riuscita dell'operazione, a parte controllare che il valore interno a quell'indirizzo di memoria sia stato portato a NULL?
    Ultima modifica di caramelleamare; 19-11-2014 a 02:21

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    ... impostare tutto il vettore a NULL al momento dell'allocazione, per usare il NULL come termine di confronto per scorrerlo fino alla prima posizione libera(NULL, appunto), e li inserire il nuovo record?
    Sì ...

    Mi resta però un dubbio sulla sulla FREE: come controllo la riuscita dell'operazione
    Non puoi ottenere nulla dalla free. La esegui e basta.

    a parte controllare che il valore interno a quell'indirizzo di memoria sia stato portato a NULL?
    Che vuoi dire? Imposti tu a NULL il puntatore dopo avere usato la free ... quest'ultima non fa nulla.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Quote Originariamente inviata da caramelleamare Visualizza il messaggio
    Pensavo una cosa: potrebbe essere una buona soluzione impostare tutto il vettore a NULL al momento dell'allocazione, per usare il NULL come termine di confronto per scorrerlo fino alla prima posizione libera(NULL, appunto), e li inserire il nuovo record?
    Come suggerisce il nostro ottimo oregon, lo puoi fare, ma senza dimenticare che stai peggiorando le prestazioni algoritmiche dell'inserimento, da O(1) (tempo costante) ad un caso medio di n/2 tipico della ricerca lineare.

    In situazioni del genere, con esercizi meno elementari, si usa una strategia di record recycling (una idea vecchia almeno quanto le schede perforate), che però al momento non ti illustrerei nei dettagli - per non correre il rischio di confonderti inutilmente le idee con nozioni ancora troppo avanzate per il tuo stato di comprensione del linguaggio e delle tecniche algoritmiche.
    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

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.