Naruszenie Ochrony Pamięci w klasie

0

Witam, muszę zrobić tablicę asocjacyjną bez używania standardowych kontenerów, z rozróżnianiem wielkości liter, i bez rozróżniania. Oczywiście kod nie może się duplikować, więc zastosowałem hierarchię klas, lecz wyrzuca mi błąd w terminalu o Naruszeniu Ochrony Pamięci i niestety nie potrafię go rozwiązać, proszę o jakieś porady. :)


#include <iostream>
#include <string.h>
#include <ctype.h>

using namespace std;

struct node
{
        node *next;
        char *key;
        int val;

        node (const char *k):next (NULL)
        {
                key = new char[strlen (k) + 1];
                strcpy (key, k);
        };

        node (const node & s):next (NULL)
        {
                if (s.key == NULL)
                        key = NULL;
                else
                {
                        key = new char[strlen (s.key) + 1];
                        strcpy (key, s.key);
                }

                val=s.val;
        };

        ~node ()
        {
                delete[]key;
        }

        private:

                node & operator= (const node &);
};

class assocTabNKS;

class assocTabKS
{
        private:
                node *head;

        protected:      
                void clear ();
                node *find (const char *key) const;
                void insert (const char *key, int value);
                void swap (assocTabKS & l);

        public:

                assocTabKS ();
                assocTabKS (const assocTabKS & l);
                assocTabKS & operator= (const assocTabKS & l);
                ~assocTabKS ();
                int &operator[] (const char *);

                friend ostream & operator<< (ostream & out, assocTabKS & l)
                {
                        node * c = l.head;
                        while (c)
                        {
                                out << c->val << " ";
                                c = c->next;
                        };

                        return out;
                };
};

class assocTabNKS : public assocTabKS
{
        private:

        protected:      

                node *find (const char *k) const;
                void insert (const char *k, int value);

        public:

                assocTabNKS ();
                assocTabNKS (const assocTabNKS & l);
                assocTabNKS & operator= (const assocTabNKS & l);

                int &operator[] (const char *k);

                friend ostream & operator<< (ostream & stream, assocTabNKS & l)
                {

                };
};

assocTabKS::assocTabKS ()
{
        head = NULL;
}

assocTabKS::assocTabKS (const assocTabKS & l)
{
        node *src, **dst;
        head = NULL;
        src = l.head;
        dst = &head;

        try
        {
                while (src)
                {
                        *dst = new node (*src);
                        src = src->next;
                        dst = &((*dst)->next);
                }
        }
        catch (...)
        {
                clear ();
                throw;
        };
}

assocTabKS::~assocTabKS ()
{
        clear ();
}

assocTabKS & assocTabKS::operator= (const assocTabKS & l)
{
        if (&l == this)
                return *this;

        node *src, **dst;
        head = NULL;
        src = l.head;
        dst = &head;

        try
        {
                while (src)
                {
                        *dst = new node (*src);
                        src = src->next;
                        dst = &((*dst)->next);
                }
        }
        catch (...)
        {
                clear ();
                throw;
        };

        return *this;
}

void assocTabKS::clear ()
{
        while (head)
        {
                node *t = head->next;
                delete head;
                head = t;
        }
}

void assocTabKS::insert (const char *key, int value)
{
        node *nowy = new node (key);
        nowy->next = head;
        head = nowy;
        head->val = value;
}

void assocTabKS::swap (assocTabKS & l)
{
        node *t = head;
        head = l.head;
        l.head = t;
}

node * assocTabKS::find (const char *key) const
{
        node * c = head;
        while (c)
        {
                if (!strcmp (c->key, key))
                        return c;
                c = c->next;
        };
        return NULL;
}

int & assocTabKS::operator[] (const char *key)
{
        node *c = find (key);

        if (!c)
        {
                insert (key, 0);
                c = head;
        };

        return c->val;
}

assocTabNKS::assocTabNKS ():assocTabKS ()
{
};

void assocTabNKS::insert (const char *k, int value)
{
        char *key = new char[strlen (k) + 1];
        char zn;
        int i = 0;

        while(*(k+i))
        {
                zn = *(k+i);
                zn = (char)tolower(zn);
                *(key+i) = zn;
                i++;
        }
        *(key+i) = '\0';

        assocTabKS::insert(key, value);

        delete [] key;
}

node * assocTabNKS::find (const char *k) const
{
        char *key = new char[strlen (k) + 1];
        char zn;
        int i = 0;

        while(*(k+i))
        {
                zn = *(k+i);
                zn = (char)tolower(zn);
                *(key+i) = zn;
                i++;
        }
        *(key+i) = '\0';

        return assocTabKS::find(key);
}

int & assocTabNKS::operator[] (const char *k)
{
        char *key = new char[strlen (k) + 1];
        char zn;
        int i = 0;

        while(*(k+i))
        {
                zn = *(k+i);
                zn = (char)tolower(zn);
                *(key+i) = zn;
                i++;
        }
        *(key+i) = '\0';

        return assocTabNKS::operator[](key);

        delete [] key;

}

int main ()
{
        assocTabKS tab1;
        tab1["ola"] = 5;
        tab1["ala"] = 10;
        cout << tab1["ala"]<<" "<<tab1["ola"]<<" "<<tab1["Ola"]<< endl;
        cout<<"-------"<<endl;
        assocTabNKS tab2;
        tab2["ola"] = 5;
        tab2["ala"] = 10;
        cout << tab1["ala"]<<" "<<tab1["ola"]<<" "<<tab1["Ola"]<< endl;
        tab2["Darek"] = 5; <-----------------------------------------------------------miejsce wystąpienia błędu.
        cout << tab1["ala"]<<" "<<tab1["ola"]<<" "<<tab1["Ola"]<< endl;
}
2

Uruchom to pod debugerem i zobacz gdzie się sypie. Nikt tego za ciebie nie zrobi.

1
  1. Zapoznaj się czemu nie należy używać i++ - http://4programmers.net/Forum/1101404
  2. Zapoznaj się z zasadą DRY
  3. Zapisz to samo w 1/4 wierszy np:
    char *smalldup(const char *key)
    {
    char *tmpkey=strdup(key);
    for(char *p=tmpkey;*p;++p) *p=tolower(*p);
    return tmpkey;
    }
    size_t &assocTabNKS::operator[] (const char *key)
    {
    char *tmpkey=smalldup(key);
    size_t &ret=assocTabNKS::operator[](small_key(key));
    free(tmpkey);  // można delete[] jeżeli przepiszesz strdup()
    return ret;
    }
  4. W trakcie przepisywania na 100% znajdziesz błąd
0

Część kodu (KS) jest od naszego prowadzącego, więc stąd i++, ale dziękuję za tą wskazówkę i postaram się teraz pisać zgodnie z Twoimi poradami. Co do 3 pkt to nadal niestety nie udało mi się odnaleźć tego błędu.

1

I nie dasz rady tego zrobić dopóki nie zajdzie jedno z 4-ch:

  1. Staniesz się średniozaawansowanym - w sekundę zobaczysz gdzie jest ptroblem
  2. Wykorzystasz punkt 3. poprzedniego postu - program się skróci do kilkudziesięciu wierszy i też zobaczysz problem
  3. Wykorzystasz poradę od @Shalom http://4programmers.net/Forum/1104382
  4. Ktoś zlituje się nad nierobem i poda gdzie jest błąd
0

Skorzystałem jednak z 3pkt, i zacząłem szukać błędu w moim kodzie i znalazłem go w [], także dziękuję za cenne wskazówki od Was. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0