2016-10-19 10 views
-6

Почему этот код вызывает ошибку сегментации? Он вызывает разлом seg в деструкторе. Но когда я называю свободную функцию без деструктора, все в порядке. Некоторые ответы не понимают проблемы. Проблема в том, что если я использую свободную функцию в main() s.free(); Это прекрасно работает .. Но я делаю деструктор делать бесплатную() работу, это не нормально.ошибка сегментации деструктора класса

#include<iostream> 
using namespace std; 

class Stack 
{ 
public: 
    int pop() { 
     data = next->data; 
     auto tmp = next; 
     next = next->next; 
     delete tmp; 
     return data; 
    } 
    void push(int n) { 
     Stack* p = new Stack(); 
     p->data = n; 
     p->next = next; 
     next = p; 
     size++; 
    } 
    virtual ~Stack() { 
     free(); 
    } 
    void free() { 
     while(next) pop(); 
    } 
    Stack* next = nullptr; 

protected: 
    int data; 
    int size = 0; 
}; 
int main() 
{ 
    Stack s; 
    for(int i=0; i<30; i++) s.push(i); 
} 
+0

Я предлагаю научиться использовать отладчик. – juanchopanza

+2

У вас есть несколько освобождений ... Когда вы создали множество 'Stack', когда вы нажимаете элементы, когда исходный стек уничтожается, вы удаляете другие, но цепочка остается ... –

+0

, но проблема в том, что если я использую свободную функцию в main() s.free(); Он отлично работает. Но я делаю деструктор делать бесплатную() работу, это не нормально. – Parker

ответ

3

Ваша pop функция уничтожает весь стек. Это deletes узел tmp (путем вызова деструктора Stack), который по-прежнему указывает на новый next. И поскольку вызов деструктора удаляет по next, вы получаете беспорядок множества вызовов деструктора на тех же объектах.

JMA избили меня на несколько секунд, поэтому обратитесь к их исправлению кода для быстрого решения.

Однако я бы рекомендовал добавить выделенную структуру Node вместо составления Stacks, это фактически увеличит ясность вашего кода.

+0

О чем ты говоришь? next = next-> next; Разве вы не видите этого? – Parker

+0

@Parker, заметьте манеры и запустите отладчик. Что означает 'tmp-> next'? – StoryTeller

+0

Извините, что вы были правы. Я не заметил, что удаление вызовет деструктор. Он отличается от malloc .. – Parker

-1

В конструкторе класса вы должны установить next = nullptr, otherwhise цикл в функции free() не остановится. Редактировать: Я думаю, проблема в том, что в поп, который вы удаляете, и который вызывает деструктор снова. попробовать это один: `

int pop() { 
    data = next->data; 
    auto tmp = next; 
    next = next->next; 
    tmp->next = nullptr; 
    delete tmp; 
    return data; 
} 

`

+4

Он предоставляет значение по умолчанию, используя функции C++ 11. – StoryTeller