C ++ новичок: деструктор - PullRequest
1 голос
/ 28 декабря 2011

Я просто создаю простой список и затем уничтожаю его.И что-то идет не так, и я всегда получаю это досадное сообщение об ошибке:

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

Вот код:

#include<iostream>
#include<Windows.h>
using namespace std;

struct node
{
    int data;
    node *next;
};

class list
{
protected:
    node *top;
public:
    list()
    {
        top=NULL;
    }

    list random()
    {
        int x=rand()%10;
        for(int i=0; i<x; i++)
        {
            node *p=new node;
            p->data=rand()%100;
            p->next=top;
            top=p;
        }
        return *this;
    }

    void show()
    {
        for(node *p=top; p; p=p->next)
        {
            cout<<p->data<<" ";
        }
        cout<<"\n";
    }

    ~list()
    {
        node *r;
        for(node *p=top; p; p=r)
        {
            r=p->next;
            delete p;
        }
    }
};

int main()
{
    srand(GetTickCount());
    list a;
    a.random().show();
    return 0;
}

Ответы [ 3 ]

3 голосов
/ 28 декабря 2011

Это:

list random()

должно быть:

list &random()

Причина в том, что ваша версия возвращает копию вашего экземпляра a, и эта копия уничтожается после вызова show(), и это уничтожение уничтожает ту же память, что и a. Если вы действительно хотите, чтобы random() возвратил копию, вам нужно реализовать конструктор копирования, который делает глубокую копию внутреннего списка, который есть у a.

0 голосов
/ 28 декабря 2011

Это не «досадное сообщение об ошибке», оно говорит вам, что ваша программа каким-то образом испортила память.На самом деле это очень важно.

Вы создаете копию своего списка, когда вы return *this, но вы никогда не определяете конструктор копирования, поэтому в итоге вы удаляете свой верхний узел дважды.

0 голосов
/ 28 декабря 2011

Ваша проблема в том, что вы копируете list, но не определяете конструктор копирования. Неявно определенный конструктор копирования просто скопирует указатель top, поэтому вы попытаетесь удалить одну и ту же цепочку узлов дважды.

Копирование происходит, когда вы return *this; из вашей функции-члена random() возвращают копию *this по значению.

Самое короткое исправление - сделать ваш класс не подлежащим копированию, объявив конструктор копирования и оператор присваивания копии в закрытом разделе вашего класса.

private:
    list(const list&);
    list& operator=(const list&);

После этого вы можете random вернуть void, кажется, нет веской причины, по которой он также делает копию.

Тогда вы можете просто назвать это так:

    list a;
    a.random();
    a.show();

Более длинное исправление - сделать list копируемым, сделав полную реализацию list(const list&) и list& operator=(const list&), которая правильно дублирует все копируемые узлы источника list.

...