Problemma nella deallocazione di vettori char

di il
8 risposte

Problemma nella deallocazione di vettori char

Ciao ragazzi sto riscontrando un problema nel deallocare la memoria adibita ad un vettore di char, la cosa interessante è che finche non dichiaro il distruttore della classe (che mi va a deallocare la suddetta stringa) non mi da problemi. Non appena dichiaro il distruttore il programma da segmentation fault in una funzione che non è il distruttore... in pratica se dichiaro il distruttore cambia il modo in cui viene allocata la memoria... per adesso non vi passo nulla di scritto, se foste interessati a capirne di più sono disposto anche a inviare il file del programma in via privata. Questa domanda è solamente per capire se qualcuno si è già trovato in questa situazione e magari ha la soluzione pronta...Grazie in anticipo

8 Risposte

  • Re: Problemma nella deallocazione di vettori char

    E perché in via privata? Cos'è, codice della NSA?
  • Re: Problemma nella deallocazione di vettori char

    #include <iostream>
    #include <cstring>
    using namespace std;
    struct app{
    app* pun;
    char* nome;
    bool foreground;
    };

    class GestoreApp {
    app* iniz;
    public:
    GestoreApp();
    GestoreApp operator += (const char[]);
    friend ostream& operator << (ostream&,const GestoreApp&);
    void foreground (const char*);
    GestoreApp operator -= (const char*);
    void chiudi_tutte();
    ~GestoreApp();
    };


    GestoreApp::GestoreApp(){
    iniz=NULL;
    }
    GestoreApp GestoreApp::operator += (const char* str){
    if (strlen(str)>20) return *this; //necessario se si vuole concatenare operazioni

    if (iniz==NULL) //normale inserimento se la lista e' vuota
    {
    iniz=new app;
    iniz->foreground=true;
    iniz->nome=new char[strlen(str)+1];
    strcpy(iniz->nome,str);
    iniz->pun=NULL;
    return *this;
    }
    app* p=iniz;
    while (p!=NULL) //controllo che non ci sia gia' avviata un app con lo stesso nome
    {
    if (!strcmp(str,p->nome)) //tolgo dal foreground l'app che lo era prima di aprire questa nuova
    return *this;
    p=p->pun;
    }
    p=iniz;
    while (p!=NULL)
    {
    if (p->foreground==true) //tolgo dal foreground l'app che lo era prima di aprire questa nuova
    p->foreground=false;
    p=p->pun;
    }
    p=iniz; //inserimento in testa se sono gia' presenti app aperte
    iniz=new app;
    iniz->foreground=true;
    iniz->nome=new char [strlen(str)+1];
    strcpy(iniz->nome,str);
    iniz->pun=p;
    return *this;

    }
    ostream& operator << (ostream& os,const GestoreApp& G){
    os<<'[';
    app* p=G.iniz;
    while (p!=NULL) //se c'e almeno una app essa e' in foregound
    {
    if (p->foreground==true)
    os<<p->nome; //la stampo tra le parentesi quadre
    p=p->pun;
    }
    os<<"]";
    if (G.iniz==NULL)
    return os;
    if (G.iniz->pun!=NULL)
    os<<", ";
    p=G.iniz;
    while (p!=NULL)
    {
    if (p->foreground!=true) //stampo tutte le rimanenti (escludo quella in foreground)
    {
    os<<p->nome;
    if (p->pun!=NULL)
    os<<", ";
    p=p->pun;
    }
    else
    p=p->pun;
    }
    os<<endl;
    return os;
    }
    void GestoreApp::foreground (const char* str){
    app* p=iniz;
    app* q=p;
    bool trovata=false;
    if (iniz==NULL) return; // se la lista e' vuota non c'e' nulla da cambiare
    while (p!=NULL) //controllo che esista una app aperta con quel nome
    {
    if (!strcmp(p->nome,str))
    {
    trovata=true;
    break;
    }
    p=p->pun;
    }
    if (trovata==false) return; //se non trovo l'app aperta non ho nessuno stato da cambiare
    p=iniz;
    while (p!=NULL) // una volta esclusi gli altri casi procedo a variare l'app in foreground
    {
    if (p->foreground==true)
    p->foreground=false;
    if (!strcmp(p->nome,str))
    {
    p->foreground=true; //cambio l'app in foreground
    q->pun=p->pun;
    p->pun=iniz; //e la sposto al primo posto
    iniz=p;
    return;
    }
    q=p;
    p=p->pun;
    }
    return;
    }
    GestoreApp GestoreApp::operator -= (const char* str){
    app* p=iniz;
    app* q=p;
    bool trovata=false;
    while(p!=NULL)
    {
    if (!strcmp(str,p->nome)) //controllo se esiste
    {
    trovata=true;
    break; //salvo in p l'indirizzo dell'elemento trovato e in q l'ind. dell'elem. prec.
    }
    q=p;
    p=p->pun;
    }
    if (trovata==false) return *this;
    else
    {
    q->pun=p->pun;
    delete p; //cancello l'app e ricucio la lista
    return *this;
    }


    }
    void GestoreApp::chiudi_tutte(){
    app* q=iniz;
    app* p=q->pun;
    delete iniz;
    while (p!=NULL)
    {
    delete q->nome;
    delete q;
    q=p;
    p=p->pun;
    }
    delete q->nome;
    delete q;
    iniz=NULL;
    return;
    }
    GestoreApp::~GestoreApp(){
    app* p=iniz->pun;
    app* q=iniz;
    while (p!=NULL)
    {
    delete[] q->nome;
    delete q;
    q=p;
    p=p->pun;
    }
    delete[] q->nome;
    delete q;
    }
  • Re: Problemma nella deallocazione di vettori char

    Intanto un particolare:
    
    GestoreApp& operator += (const char[]); // altrimenti viene invocato l'operatore di assegnamento che non c'è
    GestoreApp& operator -= (const char[]); // altrimenti viene invocato l'operatore di assegnamento che non c'è
    
    Poi nel caso :
    
    int main(etc) {
    GestoreApp gest;
    }
    
    GestoreApp::~GestoreApp(){
    app* p=iniz->pun; // quanto vale iniz qui?
    app* q=iniz;
    ...
    
    void GestoreApp::chiudi_tutte(){
    app* q=iniz; // e qui? 
    app* p=q->pun;
    
  • Re: Problemma nella deallocazione di vettori char

    La lista a cui punta iniz ha 0 elementi.. ne viene aggiunto 1 e non da nessun problema ma con il distruttore dichiarato quando cerco di stampare il 1° (e unico) elemento da errore nel cout alla riga in cui c'è scritto:
    if (p->foreground==true)
  • Re: Problemma nella deallocazione di vettori char

    No, la lista a cui punta iniz non esiste proprio!
    Ragiona: nel costruttore inizializzi iniz a NULL, nel distruttore scrivi:
    
    app* p=iniz->pun;
    
    che equivale a scrivere:
    
    app* p=NULL->pun;
    
    e lo stesso problema lo hai in chiudi_tutte() nella riga:
    app* p=q->pun;
    Tra l'altro nella stessa funzione scrivi:
    
    app* q = iniz;
    app* p = q->pun;
    delete iniz; // stessa memoria a cui ora punta q!
    ...
    delete q->nome; // q non è più valido, nome genera un memory leak 
    delete q; // altro errore perché ne q ne iniz sono reinizializzati a NULL
    iniz = NULL;
    
    se fai il delete di iniz invalidi anche q.
  • Re: Problemma nella deallocazione di vettori char

    Iniz ha un valore perchè prima di fare iniz->nome alloco un nuovo elemento di tipo app e lo eguaglio a iniz con il comando:
    iniz=new app;
    per il resto ti do pienamente ragione.

    in ogni caso non è questo l'errore che da segmentation fault. anche una volta corretto l'errore persiste
  • Re: Problemma nella deallocazione di vettori char

    Ti ripeto che iniz == NULL in questo frammento di codice:
    
    int main(etc) {
       GestoreApp gest;
    }
    
    il resto è solo una conseguenza di una tua omissione.
    in ogni caso non è questo l'errore che da segmentation fault. anche una volta corretto l'errore persiste
    Lo so bene, ma avrebbe dovuto darti un hint su come correggerlo. Basta mettere
    
    if (iniz != NULL) {
        // resto del distruttore e chiudi_tutte. 
    }
    
  • Re: Problemma nella deallocazione di vettori char

    Ho risolto infatti, i tuoi consigli sono stati preziosi, ti ringrazio
Devi accedere o registrarti per scrivere nel forum
8 risposte