Classe con puntatori

di il
12 risposte

Classe con puntatori

Salve, ho impostato una classe contenente due 4 puntatori ma mi sa che ho sbagliato qualcosa perché certe volte il programma va in crash. Questa è la dichiarazione della classe
#ifndef LIPIDTYPE_H
#define LIPIDTYPE_H

#include <string>


class LipidType
{
    friend std::ostream& operator<<(std::ostream&, const LipidType&);

    public:
        LipidType(int m=5,int l=0);
        ~LipidType();
        LipidType(const LipidType& otherlip);
        LipidType& operator=(const LipidType& otherlip);
        bool operator<(const LipidType&) const;
        bool operator>(const LipidType&) const;
        void getall(const std::string modf,const std::string classef,
                    const double intens, const double fragm);
        void getmz(const double mass);
        void getmatches(const int match);
        void getname(const std::string namelip);
        void resize(int nusize);
    protected:
    private:
        std::string *mod;
        std::string *classe;
        int matches;
        double mz;
        double *intensity;
        double *frag;
        std::string name;
        int maxsize;
        int length;
};

#endif // LIPIDTYPE_H
e questa la sua implementazione
#include "LipidType.h"
#include <iostream>

LipidType::LipidType(int m, int l)      //ctor
{
    maxsize = m;

    length = l;

    classe = new std::string [maxsize];
    mod = new std::string [maxsize];
    intensity = new double [maxsize];
    frag = new double [maxsize];
}

LipidType::~LipidType()     //dtor
{
    delete [] mod;
    delete [] classe;
    delete [] intensity;
    delete [] frag;
}

LipidType::LipidType(const LipidType& otherlip) //copy ctor
{
    *this = otherlip;
}

LipidType& LipidType::operator=(const LipidType& otherlip)  //assignment operator
{
    if (this == &otherlip) return *this; // handle self assignment

    if(otherlip.maxsize > maxsize)
    {
        std::cout << "Resizing" << std::endl;
        resize(otherlip.maxsize);
    }

    for(int i=0; i<otherlip.length; i++)
    {
        mod[i]=otherlip.mod[i];
        classe[i]=otherlip.classe[i];
        intensity[i]=otherlip.intensity[i];
        frag[i]=otherlip.frag[i];
    }

    matches=otherlip.matches;
    name=otherlip.name;
    mz=otherlip.mz;

    length = otherlip.length;

    return *this;
}

std::ostream& operator<<(std::ostream& osObject, const LipidType& lipid)
{
    osObject << lipid.name << std::endl;

    for(int i=0; i<lipid.length; i++)
    {
        osObject << '\t' << lipid.classe[i] << std::endl;
        osObject << lipid.mod[i] << '\t';
        if (lipid.mod[i].find("curs") != std::string::npos)
            osObject << lipid.frag[i] << '\t';
        else
            osObject << lipid.mz << "-" << lipid.frag[i]
                     << "=" << lipid.mz-lipid.frag[i] << '\t';
        osObject << "Intensity:" << lipid.intensity[i] << std::endl;
    }

    osObject << "Matches: " << lipid.matches << std::endl;

    return osObject;
}

void LipidType::getall(const std::string modf,const std::string classef,
                    const double intens, const double fragm)
{
    if(length+1 > maxsize)
        resize(maxsize*2);

    mod[length] = modf;
    classe[length] = classef;
    intensity[length] = intens;
    frag[length] = fragm;

    length++;
}

void LipidType::getmz(const double mass)
{
    mz = mass;
}

void LipidType::getmatches(const int match)
{
    matches = match;
}

void LipidType::getname(const std::string namelip)
{
    name=namelip;
}

void LipidType::resize(int nusize)
{
        std::cout << "Dentro resize." << std::endl;
        maxsize = nusize;
        std::string* temp1=new std::string[maxsize];
        std::string* temp2=new std::string[maxsize];
        double* temp3=new double[maxsize];
        double* temp4=new double[maxsize];

        for(int i=0; i<length; i++)
        {
            temp1[i]=mod[i];
            temp2[i]=classe[i];
            temp3[i]=intensity[i];
            temp4[i]=frag[i];
        }

        delete [] mod;
        delete [] classe;
        delete [] intensity;
        delete [] frag;

        mod=temp1;
        classe=temp2;
        intensity=temp3;
        frag=temp4;

        std::cout << "fine resize";
}

bool LipidType::operator<(const LipidType& otherlip) const
{
    return(matches<otherlip.matches);
}

bool LipidType::operator>(const LipidType& otherlip) const
{
    return(matches>otherlip.matches);
}
A sentimento direi che c'è qualcosa che non va nell'assegnazione o nella funzione resize ma non riesco a capire cosa.

P.S. una domanda: ho code::blocks; come si fa a trovare il blocco di un programma con il debugger?

12 Risposte

  • Re: Classe con puntatori

    Qual'è la differenza tra maxsize e length? Se length è maggiore di maxsize quì hai un buffer overflow
    for(int i=0; i<otherlip.length; i++)
        {
            mod[i]=otherlip.mod[i];
            classe[i]=otherlip.classe[i]; 
            intensity[i]=otherlip.intensity[i];
            frag[i]=otherlip.frag[i];
        }
    così come nella funzione resize
    for(int i=0; i<length; i++)
            {
                temp1[i]=mod[i];
                temp2[i]=classe[i];
                temp3[i]=intensity[i];
                temp4[i]=frag[i];
            }
  • Re: Classe con puntatori

    Maxsize è la lunghezza massima teorica dei vettori mentre length è la lunghezza effettiva (quanti elementi ho inserito effettivamente nel vettore). Aggiungo elementi ai vettori attraverso la funzione getall che controllo che length+1 non sia mai superiore a maxsize, in questo caso estende maxsize al doppio della sua lunghezza(espandendo anche i vettori) quindi la condizione di overflow non si dovrebbe mai verificare
  • Re: Classe con puntatori

    Fai un esempiominimo dove si verifica il crash, compreso il main così lo posso verificare col debbugger.
  • Re: Classe con puntatori

    Il main è questo
    #include <iostream>
    #include <fstream>
    #include <list>
    #include <string>
    #include <cmath>
    
    #include "LipidType.h"
    
    using namespace std;
    
    double findinten(string filename, double picco);
    void sort(LipidType* &lip,int leng);                  // insertion sort decrescente
    void resiz(LipidType* &lip,int leng,int maxsiz);
    
    int main()
    {
        LipidType *lipid;
        list<double> fraglist;
        list<double>::iterator myIt;
        string sdfname, namelip, lineflag;
        string discard,classe, mod;
        ifstream insdf,infrag;
        ofstream out;
        double frag, fragtemp, mz;
        char ch;
        int matches;
        int maxsize = 20;
    
        cout << "SDF file:";
        getline(cin,sdfname);
    
        cout << "Pos or neg(p/n):";
        cin >> ch;
    
        insdf.open(sdfname.c_str());
    
        unsigned int len;
    
        len = static_cast<unsigned int>(sdfname.length());
    
        sdfname[len-3] = 't';
        sdfname[len-2] = 'x';
        sdfname[len-1] = 't';
    
        out.open(sdfname.c_str());
    
        int nlip=0;
        lipid = new LipidType[maxsize];
    
        while(insdf>>namelip)
        {
            if(nlip+1 > maxsize)
                resiz(lipid,nlip,maxsize*2);
    
            lipid[nlip].getname(namelip);
    
            for(int i=0; i<20; i++)        // ignora un po' di righe inutili
                insdf.ignore(1000,'\n');
    
            getline(insdf,lineflag);
            size_t found = lineflag.find("FRAGMENT_MATCHES");
    
            while(found == string::npos)
            {
                getline(insdf,lineflag);
                found = lineflag.find("FRAGMENT_MATCHES");
            }
    
            // cominciano i frammenti
    
            while(insdf >> frag)
                fraglist.push_back(frag);
    
            insdf.clear();
    
            // ricerco matches count
    
            getline(insdf,lineflag);
            insdf >> matches;
            lipid[nlip].getmatches(matches);
    
            // ricerco picco parente
    
            getline(insdf,lineflag);
            found = lineflag.find("MSMS");
    
            while(found == string::npos)
            {
                getline(insdf,lineflag);
                found = lineflag.find("MSMS");
            }
    
            for(int i=0; i<3; i++)
                insdf >> discard;
    
            insdf >> mz;                   // picco parente
            lipid[nlip].getmz(mz);
            insdf >> discard;              // legge $$$$
    
            if(ch == 'p')
                infrag.open("IN-POS.txt");      //apro file con i frammenti templato
            else
                infrag.open("IN-NEG.txt");
    
            for(int i=0; i<5; i++)
            {
                infrag >> discard >> classe >> mod >> fragtemp;
    
                if (namelip.find("LMGP") != string::npos)
                    if (mod.find("curs") != string::npos)
                    {
                        for(myIt=fraglist.begin(); myIt!=fraglist.end(); ++myIt)
                            if (fabs(*myIt-fragtemp)< 1)
                            {
                                lipid[nlip].getall(mod,classe,findinten(sdfname,*myIt),*myIt);
                                break;
                            }
                    }
                    else
                    {
                        for(myIt=fraglist.begin(); myIt!=fraglist.end(); ++myIt)
                            if (fabs((mz-(*myIt))-fragtemp)<1)
                            {
                                lipid[nlip].getall(mod,classe,findinten(sdfname,*myIt),*myIt);
                                break;
                            }
                    }
            }
    
            while(infrag)
            {
                infrag >> discard >> classe >> mod >> fragtemp;
    
                if (mod.find("curs") != string::npos)
                    {
                        for(myIt=fraglist.begin(); myIt!=fraglist.end(); ++myIt)
                            if (fabs(*myIt-fragtemp)< 1)
                            {
                                lipid[nlip].getall(mod,classe,findinten(sdfname,*myIt),*myIt);
                                break;
                            }
                    }
                else
                {
                    for(myIt=fraglist.begin(); myIt!=fraglist.end(); ++myIt)
                        if (fabs((mz-(*myIt))-fragtemp)<1)
                        {
                            lipid[nlip].getall(mod,classe,findinten(sdfname,*myIt),*myIt);
                            break;
                        }
                }
            }
            fraglist.clear();
            infrag.close();
    
            nlip++;
        }
    
        cout << "Fin qui tutto ok" << endl;
    
        sort(lipid,nlip);
    
        for(int i=0; i<nlip; i++)
            out << lipid[i];
    
        out.close();
    
        return 0;
    }
    
    double findinten(string filename, double picco)
    {
        ifstream inn;
        string mystr;
        string discard;
        double varx,vary;
    
        unsigned int len;
    
        len = static_cast<unsigned int>(filename.length());
    
        filename[len-3] = 'C';
        filename[len-2] = 'E';
        filename[len-1] = 'F';
    
        for(int i=0; i<len; i++)
            if(filename[i] == '-')
                filename[i] = '.';
    
        inn.open(filename.c_str());
    
        for(int i=0; i<5; i++)          // ignora un po' di righe inutili dopo l'intestazione
            inn.ignore(1000,'\n');             // relativa a quella d'interesse
    
        mystr = " ";
    
        int volte=0;
    
        while(volte != 2)
        {
            getline(inn,mystr);
    
            if (mystr.find("<MSPeaks>") != string::npos)
                volte++;
        }
    
        char dischar;
    
        inn >> discard;
    
        for(int i=0; i<3; i++)
            inn >> dischar;
    
        inn >> varx;
    
        while (discard.find("</MSPeaks>") == string::npos)
        {
            if(fabs(varx-picco)<0.05)
            {
                inn >> dischar;
    
                for(int i=0; i<3; i++)
                    inn >> dischar;
    
                inn >> vary;
    
                inn.close();
    
                return vary;
            }
            else
            {
                inn.ignore(1000,'\n');
    
                inn >> discard;
    
                for(int i=0; i<3; i++)
                    inn >> dischar;
    
                inn >> varx;
            }
        }
    
        inn.close();
    
        return 1;
    }
    
    void sort(LipidType* &lip,int leng)
    {
        int location;
        LipidType temp;
    
        for(int i=0;i<leng-1;i++)
        {
            location=i+1;
            temp = lip[location];
    
            while(location>0 && temp>lip[location-1])
            {
                lip[location] = lip[location-1];
                location--;
            }
            lip[location] = temp;
        }
    }
    
    void resiz(LipidType* &lip,int leng,int maxsiz)
    {
        LipidType *temp= new LipidType[maxsiz];
    
        for(int i=0;i<leng;i++)
            temp[i]=lip[i];
    
        delete [] lip;
    
        lip = temp;
    }
    però ti servono i due file di input. Sono un po' lunghetti, te li riporto come testo sul forum o te li mando con uno zip(se mi spieghi come allegare i file su MP mi faresti un piacere )?
  • Re: Classe con puntatori

    Allora per debuggare con code::block basta premere il pulsante play rosso,in alternativa debug->start oppure F8.
    Per mettere un brekpoint vai sulla linea interessata e premi F5 oppure clicca a destra del numeroriga.
  • Re: Classe con puntatori

    Ma fino a quel punto lo so fare; il problema è che quando vado con lo step into su alcune istruzioni, scompare la freccetta gialla e si blocca il debug. Il problema è che si blocca in parti di codice che magari vanno benissimo senza arrivare alla parte incriminata.
  • Re: Classe con puntatori

    Ti ho mandato un MP.
  • Re: Classe con puntatori

    Piccola modifica nella riga 54 del main
    if(nlip+1 > maxsize)
    {
        resiz(lipid,nlip,maxsize*2);
        maxsize = nlip;
    }
    Chiedevi sempre memoria perche maxsize non veniva aggiornato.
  • Re: Classe con puntatori

    skynet ha scritto:


    Ti ho mandato un MP.
    Mi sono perso ...
  • Re: Classe con puntatori

    Mi ha mandato i file di input dove poi sono riuscito a vedere l'errore niente di che.
  • Re: Classe con puntatori

    skynet ha scritto:


    Mi ha mandato i file di input dove poi sono riuscito a vedere l'errore niente di che.
    No ... nulla ... era solo per curiosità ... stavo seguendo il discorso sul forum e quindi non mi ritrovavo con la tua ultima risposta ...
  • Re: Classe con puntatori

    Grande! Mi hai risolto una grandissima seccatura, ti ringrazio.
Devi accedere o registrarti per scrivere nel forum
12 risposte