Zarządzanie pamięcią

0

Witam, mam problem z zarządzaniem pamięcią w stosie. Valgrind wskazuje mi 1 błąd, zauważyłem też że powodem tego błędu jest to że zwalniam więcej niż zalokowałem, oraz gdy dam w komentarz 154 linijkę kodu stos.-stack() jest wszystko dobrze. Zupełnie nie mam pojęcia gdzie popełniłem błąd, bo zapewne ta linijka musi być?

Proszę o jakąś wskazówkę, od bardziej doświadczonych w tym temacie. :)

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
using namespace std;

class stack{
public:
        stack(); //konstruktor
        ~stack(); //destruktor
        void clear(); //czyszczenie stosu
        void push(int a); //dodanie elementu 
        int pop(); // pobranie
        int getStackSize();  //aktualny rozmiar stosu
        void show(); //wyswietlenie stosu
stack (int size); konstruktor z zadanym rozmiarem stosu
private:
        int size; // rozmiar stosu
        int top; // pozycja ostatniego elementu
        int* dane; //stos
};
stack::stack(int Nsize)
{
dane= new int [Nsize];
size=Nsize;
}

stack::stack(){
    this->top = 0;
    this->size = 0;
    this->dane = NULL;
}

stack::~stack() {

                   delete[] this->dane;
    }

void stack::clear() {
         this->top=0;
         cout<<"Stos wyczyszczono.";
    }

void stack::push(int a) {

 
    int newsize = (this->size+1);
    int *ndane = new int[newsize];
    if (ndane)
    {
     for(int i = 0; i <this->size; i++)
      *(ndane+i) = *(this->dane+i);
      delete [] this->dane;
      this->dane = ndane;
    }
    else
    {
      delete(this->dane);
      abort();
    }
    this->size = newsize;

  this->dane[this->top++] = a;

}

int stack::pop() {
        if (top>0)
        {
                   this->top--;
                   cout<<"Usunieto ostatnia liczbe ze stosu.\n";
        }
        else
        {
                   cout<<"Brak elementów do usuniecia.\n";
        }
        }

void stack::show() {
        int j=top;
        cout<<"Na stosie znajduje sie "<<top<<" liczb.";
        cout<<"Te liczby to:";

     for(int i=0;i<j;i++)
        {
            cout<<dane[i];
        }
    }

int stack::getStackSize()
    {
        cout<<"Stos ma rozmiar "<<size<<" wyrazów.";
    }

int main()
    {
        int liczba;
        int i,key=1,wybr;
        stack stos;
        stack();

        stos.push(1);
        stos.push(2);
        stos.push(3);
        stos.push(5);

        while(key!=0)
        {
              cout<<"Co chcesz zrobic?\n";
              cout<<"1-Push()\n";
              cout<<"2-Pop()\n";
              cout<<"3-Clear()\n";
              cout<<"4-Size\n";

              cin>>wybr;
              switch(wybr)
              {
            case 1:
                cout<<"Dodanie liczby do stosu: "<<endl;
                cout<<"Wprowadz liczbe: ";
                cin>>liczba;
                stos.push(liczba);
            break;

            case 2:
                            cout<<"Pobieranie ze stosu liczby: ";
                                         stos.pop();
            break;
            case 3:
                            cout<<"Usuwanie stosu ";

                                         stos.clear();

            break;
            case 4:
                            stos.getStackSize();
            break;
              }
  stos.show();

              cout<<endl;
              cout<<"Kontynuowac? 1-tak 0-nie: ";
              cin>>key;
              system("cls");
              stos.show();

        }
        stos.show();
        stos.~stack();
        cout<<"\n\n";
        return 0;
    }
 
0

@damianeqe, a spróbuj w 154 linii stos.stack::~stack();?

0

@bajos zachowuje się tak samo jak opisałem :/

1

zauważyłem też że powodem tego błędu jest to że zwalniam więcej niż zalokowałem
W którym miejscu?

bo zapewne ta linijka musi być?
Nie, destruktor jest po to żeby sam się wywołał gdy obiekt wychodzi poza zakres. Ręczne wywołanie destruktora jest potrzebne tylko w nielicznych przypadkach.

0

@twonek jeżeli mam destruktor to alokuje (przy rozmiarze stosu 4elementy) 4allocs i mam 5 frees, jeżeli dam w komentarz tą linijkę 154 wszystko jest okej.

1

Gdzie masz te 5 deletes, bo nie widzę? Zauważ, że przy pierwszym pushu
dane == NULL, więc delete[] dane nic nie robi.

0

Gdy używam valdrind by sprawdzić pamięć, i kompilując kod z destruktorem mam 4allocs i 5 zwolnień, a usuwając wpis z 154 linii stos.~stack(), tak jak zaleciłeś mam 4alokacje 4 zwolnienia, więc jest w porządku, tylko myślałem że trzeba użyć w kodzie destruktor przed zakończeniem działania programu.

0

W takim razie dziękuję za pomoc :)

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