2015-02-23 54 views
1

該程序應該採用後綴算術表達式,然後編譯該表達式的值..每次讀取整數時,它將被推入堆棧中。否則,兩個整數將是如果讀取了+, - ,*,則彈出。調用堆棧打印函數時無限循環

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的'堆棧:: print'方法? – SHR 2015-02-23 22:00:59

+3

更好的問題:你爲什麼要在你的**'Stack :: push' **函數中刪除temp;'那根本不應該在那裏。 – WhozCraig 2015-02-23 22:03:17

+0

與Java不同,C++沒有垃圾收集器。如果我沒有刪除它,我會失去內存。delete temp;是在循環之外..我不認爲它會導致無限循環。 – Raghad 2015-02-23 22:03:39

回答

3

問題,我看到:

  1. 使用deletepush()

    void Stack::push(int data) 
    { 
        Node * temp = new Node(data); 
        temp->next = head; 
        head = temp; 
        delete temp; // This needs to go. 
    } 
    
  2. pop()不使用delete

    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. print()使用delete

    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

對不起,但我沒有得到第四個。你能告訴我你的意思是「//頭的舊值已經消失了,這是內存泄漏。」? – Raghad 2015-02-23 22:47:46

+0

@Raghad,如果你沒有實現析構函數,那麼爲節點分配的內存將不會被釋放。我有一種感覺,你應該在'push()'中嘗試這樣做,但那不是正確的地方。您需要分配的內存,直到從堆棧中彈出某個項目或該對象超出範圍。 – 2015-02-23 22:51:57

+0

@Raghad,關於「//頭的舊值已經消失,這是一個內存泄漏」,假設你在堆棧中有兩個項目 - 1和2,如果彈出頂部,堆棧將只有2個。如果不刪除對應於1的節點,則爲該節點分配的內存不會被解除分配,並且是內存泄漏。 – 2015-02-23 22:53:55

1

這是對pushpop的建議。

試圖理解邏輯。

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; 
} 

而且,而是所有的if/else,代碼中的每一個數字,你可以做如下:

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

但我不認爲有任何數字被推入堆棧cus打印功能沒有打印任何東西。而在流行()你沒有使用溫度..所以我不認爲我們需要創建一個臨時節點並刪除它。 – Raghad 2015-02-23 22:32:25