2015-02-23 3 views
1

Эта программа должна принимать постфиксное арифметическое выражение, а затем компилирует значения этого выражения. Каждый раз, когда целое число считывается, его собираются вставлять в стек. В противном случае два целых числа будут popped if +, -, *.Бесконечный цикл при вызове функции печати стека

class Stack { 
    Node *head; 

public: 
    Stack() { 
     head = NULL; 
    }; 

    void push(int data); 
    int pop(); 
    bool isEmpty(); 
    void print(); 
}; 

void Stack::push(int data) 
{ 
    Node * temp = new Node(data); 
    temp->next = head; 
    head = temp; 
    delete temp; 
} 

int Stack::pop() 
{ 
    int x = head->data; 
    head = head->next; 
    return x; 
} 

bool Stack::isEmpty(){ 
    return head == NULL; 
} 

void Stack::print(){ 
    Node * temp = head; 
    while (temp != NULL){ 
     cout << temp->data << " "; 
     temp = temp->next; 
    } 
    delete temp; 
} 


int main() { 

    Stack st; 
    char exp [] = "23+", c; 
    int i, a; 

    for (i = 0; exp[i] != '\0'; i++){ 
     c = exp[i]; 

     if (c == '+'&&!st.isEmpty()){ 
      a = st.pop() + st.pop(); 
      st.push(a); 
     } 
     else if (c == '-'&&!st.isEmpty()){ 
      a = st.pop() - st.pop(); 
      st.push(a); 
     } 
     else if (c == '/'&&!st.isEmpty()){ 
      a = st.pop()/st.pop(); 
      st.push(a); 
     } 
     else if (c == '*'&&!st.isEmpty()){ 
      a = st.pop() * st.pop(); 
      st.push(a); 
     } 
     else if (c == '0') 
      st.push(0); 
     else if (c == '1') 
      st.push(1); 
     else if (c == '2') 
      st.push(2); 
     else if (c == '3') 
      st.push(3); 
     else if (c == '4') 
      st.push(4); 
     else if (c == '5') 
      st.push(5); 
     else if (c == '6') 
      st.push(6); 
     else if (c == '7') 
      st.push(7); 
     else if (c == '8') 
      st.push(8); 
     else if (c == '9') 
      st.push(9); 

     cout << c << endl; 
     st.print(); 
    } 
    cin >> a; 
    return 0;  
} 

Когда я вызываю функцию печати в основном, я получаю бесконечный цикл как выход .. Я попытался ищу вещь, которая вызывает бесконечный цикл, но я не мог найти его.

+0

Почему вы 'удалить темп,' когда он равен NULL в Stack :: print' метод '? – SHR

+3

Лучший вопрос: почему вы «удаляете temp;' в вашей ** 'Stack :: push' ** функции ???? Этого не должно быть вообще. – WhozCraig

+0

В отличие от Java, C++ не имеет сборщика мусора. Если я не удалю его, я выйду из памяти .. delete temp; находится вне цикла. Я не думаю, что он вызывает бесконечный цикл. – Raghad

ответ

3

Проблемы, которые я вижу:

  1. Использование delete в push()

    void Stack::push(int data) 
    { 
        Node * temp = new Node(data); 
        temp->next = head; 
        head = temp; 
        delete temp; // This needs to go. 
    } 
    
  2. Не используя delete в pop():

    int Stack::pop() 
    { 
        // Problem 1. 
        // What if head is NULL? 
    
        int x = head->data; 
    
        // Problem 2 
        // The old value of head is gone. It's a memory leak. 
        head = head->next; 
        return x; 
    } 
    

    Понадобится:

    int Stack::pop() 
    { 
        if (head != NULL) 
        { 
         int x = head->data; 
         Node * temp = head; 
         head = head->next; 
         delete temp; 
         return x; 
        } 
        else 
        { 
         // Figure out what you want to do if head is NULL 
        } 
    } 
    
  3. delete Использование в print().

    void Stack::print(){ 
        Node * temp = head; 
        while (temp != NULL){ 
         cout << temp->data << " "; 
         temp = temp->next; 
        } 
        delete temp; // This needs to go. 
    } 
    
  4. Отсутствует определяемый пользователем деструктор. Вам нужно удалить объекты в объекте. В противном случае вы будете утечки памяти. Что-то в соответствии с приведенным ниже кодом должно работать.

    Stack::~Stack() 
    { 
        while (head) 
        { 
         Node * temp = head; 
         head = head->next; 
         delete temp; 
        } 
    } 
    
+0

Извините, но я не получил номер 4. И вы могли бы рассказать мне, что вы подразумеваете под «// Старое значение головы ушло. Это утечка памяти»? – Raghad

+0

@Raghad, если вы не реализуете деструктор, память, выделенная для узлов, не будет освобождена. У меня такое чувство, что вы пытаетесь сделать это в 'push()', но это не то место. Вам нужна выделенная память, пока вы не вытащите элемент из стека, или объект не выходит за рамки. –

+0

@ Raghad, относительно «// Старое значение головы ушло. Это утечка памяти», скажем, у вас есть два элемента в стеке - 1 и 2. Если вы попадете вверху, стек будет иметь только 2. Если вы не удаляете узел, соответствующий 1, память, выделенная для этого узла, не освобождается, и это утечка памяти. –

1

Вот предложение для push и pop.

попытайтесь понять логику.

void Stack::push(int data) 
{ 
    Node * temp = new Node(data); 
    temp->next=head; 
    head=temp; 
    //Do not delete temp; deleting temp will delete the new added Node 
} 

int Stack::pop() 
{ 
    Node* temp = Head; 
    int x=head->data; 
    head=head->next; 
    delete temp; //here you free the released memory. 
    return x; 
} 

Кроме того, вместо того, чтобы все, если/иначе, для каждой цифры в коде, вы можете сделать следующее:

else if(c>=0 && c<=9){ 
    st.push(c-'0'); 
} 
+0

Но я не думаю, что какое-то число попадает в стек, поскольку функция печати ничего не печатает. И в pop() вы не использовали temp .. Поэтому я не думаю, что нам нужно создать временный узел и удалить его. – Raghad