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

    [C] Eccezione sollevata dalla free(void*) per deallocare un'area di memoria allocata con la malloc()

    Salve a tutti, ho i seguenti file di testo:

    listino.txt:
    codice:
     
    acqua fiuggi 7.0
    acqua recoaro 6.0
    pasta barilla 0.3
    pasta dececco 0.5

    venduti.txt:
    codice:
    acqua recoaro
    acqua recoaro
    pasta barilla
    pasta barilla
    acqua recoaro
    pasta dececco

    Devo fare un programma che, chiesto all'utente una tipologia di prodotto(Es. acqua o pasta)
    stampi a video per ogni marca di quel prodotto(Es. per l'acqua le marche sono recoaro e fiuggi)
    nome della marca, prezzo(un float) e il numero di campioni venduti.

    Per esempio, se si sceglie acqua come tipologia l'output sarà:
    codice:
    Marca: recoaro   prezzo:6.0  esemplari venduti:3
    Marca: fiuggi   prezzo:7.0    esemplari venduti:0

    Io ho fatto il programma e funzionerebbe bene a parte il fatto che proprio su una delle ultime istruzioni, una free() chiamata per deallocare un'area di memoria allocata tramite malloc(), mi parte un'eccezione.

    Ecco il codice:
    codice:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define DIM 11
    //Item=Struttura contenente l'informazione completa su un prodotto cioè: tipologia, marca, prezzo, campioni venduti
    typedef struct{
        char tipologia[DIM], marca[DIM];
        float prezzo;
        int venduti;
    } item;
    
    
    //Questa funzione riceve i due file e una tipologia, alloca lo spazio necessario a contenere tutti gli item relativi alla tipologia(Che si distinguono per la marca)  tramite malloc, in tale spazio salva tali item e restituisce l'indirizzo(final) a tale area di memoria. Inoltre salva la quantità di item messi in final tramite il parametro size. Qui è chiamata la malloc() ma non la free().
    item* articoli(FILE *listino, FILE *venduti, char *tipologia, int *size){
        item temp, *final;
        int i=0;
        *size=0;
        while(fscanf(listino, "%s %s %f\n", temp.tipologia, temp.marca, &(temp.prezzo))==3)
            if(!strcmp(temp.tipologia, tipologia))
                (*size)++;
        final=(item*) malloc(*size*sizeof(item));          //VIENE INVOCATA LA MALLOC
    
    
        rewind(listino);
        while(fscanf(listino, "%s %s %f\n", final[i].tipologia, final[i].marca, &(final[i].prezzo))==3)
            if(!strcmp(final[i].tipologia, tipologia))
                i++;
        for(i=0; i<*size; i++){
            final[i].venduti=0;
            while(fscanf(venduti, "%s %s\n", temp.tipologia, temp.marca)==2)
                if(!strcmp(temp.tipologia, tipologia) && !strcmp(temp.marca, final[i].marca))
                    final[i].venduti++;
            rewind(venduti);
        }
    
    
        return final; //Viene restituito l'indirizzo che punta all'area di memoria allocata tramite malloc()
    }
    
    
    
    
    //Il main
    void main(){
        FILE *listino, *venduti;
        char tipologia[DIM];
        int size, i;
        item *goods;
        printf("Tipologia di prodotto desiderata: ");
        scanf("%s", tipologia);
        if((listino=fopen("listino.txt", "rt"))==NULL || ((venduti=fopen("venduti.txt", "rt"))==NULL)){
            perror("Impossibile aprire un file desiderato");
            exit(1);
        }
        goods=articoli(listino, venduti, tipologia, &size);//goods diventa il puntatore che punta all'area allocata con la malloc() nella funzione articoli()
        fclose(listino);
        fclose(venduti);
        printf("Statistiche relative alla tipologia di prodotto ""%s""\n", tipologia);
        for(i=0; i<size; i++)
            printf("Marca:%s prezzo:.2%f$ esemplari venduti:%d\n", goods[i].marca, goods[i].prezzo, goods[i].venduti);
        free(goods);        //ISTRUZIONE CHE SOLLEVA L'ECCEZIONE. SI USA LA FREE PER LIBERARE LA MEMORIA ALLOCATA CON LA MALLOC.
    
    
    system("PAUSE");
    }

    Questo è il messaggio che compare quando parte l'eccezione:
    codice:
    'Es4.exe': caricato 'C:\Users\Matteo\Documents\Visual Studio 2010\Projects\Es4\Debug\Es4.exe', Simboli caricati.
    'Es4.exe': caricato 'C:\Windows\System32\ntdll.dll', Impossibile trovare o aprire il file PDB
    'Es4.exe': caricato 'C:\Windows\System32\kernel32.dll', Impossibile trovare o aprire il file PDB
    'Es4.exe': caricato 'C:\Windows\System32\KernelBase.dll', Impossibile trovare o aprire il file PDB
    'Es4.exe': caricato 'C:\Windows\System32\msvcr100d.dll', Simboli caricati.
    HEAP[Es4.exe]: Heap block at 003E1C00 modified at 003E1C6C past requested size of 64
    Windows ha generato un punto di interruzione in Es4.exe.
    
    
    Ciò può essere dovuto a un danneggiamento dell'heap che indica un bug in Es4.exe o in una qualunque delle DLL che ha caricato.
    
    
    È anche possibile che l'utente abbia premuto F12 mentre Es4.exe era attivo.
    
    
    Controllare la finestra di output per ulteriori informazioni diagnostiche.
    Il programma '[2572] Es4.exe: Nativo' è terminato con il codice 0 (0x0).

    A cosa è dovuto questa eccezione e cosa posso fare per rimediare? Grazie in anticipo.
    N.B.:Il codice postato è diviso su più file nel progetto originario, inoltre la scelta della struttura del programma non è mia ma ce l'ha imposta il professore, quindi vi prego di non proporre soluzioni che comportino un cambio radicale della struttura del programma.

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    La causa dell'errore è subdola ...

    Il fatto è che la malloc prevede lo spazio per 2 elementi ma il ciclo seguente legge oltre il secondo item in memoria.

    In questo modo la memoria viene corrotta e la free manifesta solamente il problema.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Ok grazie mille!

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.