2012-12-31 63 views
0

我想寫一個函數,它使用雙向鏈表來計算第N個斐波那契數,但由於某種原因,當我編譯並運行鏈表時,它並不會停止增長,它會一直添加一次又一次的數字沒有結束。C++鏈表不停止增長

這應該是一個SSCCE:

#include <iostream> 
using namespace std; 


class node { 
    public: 
     int value; 
     node* previous; 
     node* next; 
};//node 

class number { 
    public: 
     node* start; 
     node* end; 
     node* add (int value); 
     void show (int K); 
     number(); 
     void destroy(); 

     void copy (number gg1); 
     void addition (number gg1, number gg2, int K); 

     void fibonacci (int K, int times); 

};//number 

number::number() { 
    start = NULL; 
    end = NULL; 
} 

int power (int K) { 
    int L = 1; 
    for (int i = (K-1); i > 0; i--) { 
     L = L*10; 
    } 
    return L; 
} 

int checksize (int value) { 
    int counter = 0; 
    while (value != 0) { 
     value = value/10; 
     counter += 1; 
    } 
    return counter; 
} 

void number::show (int K) { 
    node* current; 
    cout << "\nValue:" << endl; 
    if (start == NULL) { 
     cout << "\nNothing\n" << endl; 
    } 
    if (start != NULL) { 
     current = start; 
     while (current != NULL) { 
      if (current->value == 0) { 
       for (int i = 0; i < K; i++) { 
        cout << "0"; 
       } 
      cout << "\n"; 
      } 
      else { 
       int size = checksize (current->value); 
       for (int j = size; j < K; j++) { 
        cout << "0"; 
       } 
      cout << current->value << endl; 
      } 
      current = current->next; 
     } 
    } 
    //cout << "\n"; 
} 

int main() { 
    number gg1; 
    number gg2; 
    number gg3; 
    const int K = 5; 

    gg1.fibonacci (K, 10); 
} 

node* number::add(int value) { 
     node* currentcode;     
     if (start == NULL){      
      currentcode = new node;  
      start = currentcode;    
      end = currentcode;    
      currentcode->next = NULL;  
      currentcode->previous = NULL;  
      currentcode->value = value; 
      return currentcode; 
     } 
     if (start != NULL) {      
      currentcode = new node;  
      currentcode->next = NULL; 
      end->next = currentcode; 
      currentcode->previous = end; 
      end = currentcode;   
      currentcode->value = value; 
      return currentcode; 
     } 
     return NULL; 
} 

void number::addition (number gg1, number gg2, int K) { 
    int value1, value2, value3; 
    int carry = 0; 
    node* current1; 
    node* current2; 
    current1 = gg1.start; 
    current2 = gg2.start; 
    while (current1 != NULL || current2 != NULL) { 
     if (current1 != NULL && current2 !=NULL) { 
      value1 = current1->value; 
      value2 = current2->value; 
      value3 = value1 + value2 + carry; 
      current1 = current1->next; 
      current2 = current2->next; 
     } 
     else if (current1 == NULL && current2 != NULL) { 
      value3 = current2->value + carry; 
      current2 = current2->next; 
     } 
     else if (current1 != NULL && current2 == NULL) { 
      value3 = current1->value + carry; 
      current1 = current1->next; 
     } 

     checksize(value3); 
     if (value3 > power(K)) { 
      value3 = value3 - 10*(power(K)); 
      carry = 1; 
     } 
     else 
      carry = 0; 

     add(value3); 

     if ((current1 == NULL && current2 == NULL) && (carry == 1)) 
      add(1); 
    } 
} 

void number::destroy() { 
    node* current; 
    node* current2; 
    if (start != NULL) { 
     current = start; 
     current2 = current->next; 
     while (current2 != NULL) { 
      delete current; 
      current = current2; 
      current2 = current->next; 
     } 
     delete current; 
    } 
} 

void number::fibonacci (int K, int times) { 
    number g1; 
    number g2; 
    number g3; 
    destroy(); 

    g1.add (1); 
    g2.add (1); 

    g3.addition (g1, g2, K); 
    g2.copy(g1); 

    g1.show(K); 
    g2.show(K); 

     //g1.copy(g3); 

     //g1.show(K); 
     //g2.show(K); 
     //g3.show(K); 

     //g3.addition (g1, g2, K); 
     //g3.show(K); 
     //g2.copy(g1); 
     //g1.copy(g3); 

    /*for (int i = 0; i < 2; i++) { 
     g3.addition (g1, g2, K); 
     g3.show(K); 
     g2.copy(g1); 
     g1.copy(g3); 
    }*/ 

    copy(g3); 
} 

void number::copy (number gg1) { 
    int value; 
    destroy(); 
    node* current = gg1.start; 
    while (current != NULL) { 
     value = current->value; 
     add(value); 
     current = current->next; 
    } 
} 

每當我跑的斐波那契功能它給了我無窮的1的終端。 number class只是一個基本的雙向鏈接指針列表。

附加功能standalone工作得很好,副本也是如此。事實上,一切都很好,直到這一點。用for循環完成該功能很容易,但是這個錯誤阻止了我這樣做。有誰知道我的錯誤是什麼?提前致謝。

+3

什麼是'刪除();'在那裏做什麼,爲什麼是不是編譯錯誤? –

+0

如何使用刪除功能作爲您定義的功能?它一定給了你錯誤。或者你只是在寫這個代碼。只是提供'添加'功能。 – Alfred

+1

「它不斷**添加**一個數字」。也許看到'add()'和'addition()'也可能有一些好處? – WhozCraig

回答

0

現在,您的存儲器訪問無效,因爲在destroy()的每個節點上調用delete不會使內存空出來,但它只會標記內存空閒。

建議修正:

void number::destroy() { 
    node* current; 
    node* current2; 
    if (start != NULL) { 
     current = start; 
     current2 = current->next; 
     while (current2 != NULL) { 
      delete current; 
      current = current2; 
      current2 = current->next; 
     } 
     delete current; 
    } 
    start = NULL; // so you can't access the now non-existing list anymore. 
    end = NULL; 
} 

備註:

  • 類名應該是資本首先通過廣泛適應約定。
  • 你不應該在你的拷貝和加法函數中通過值來傳遞一個類,而是const-ref。
  • 在這種情況下更好地使用operator=而不是copycopy可以是copy_fromcopy_to,調用函數copy確實是非常模糊的。
  • 總是更好地使用for循環,當你可以。
  • Node不是一個類,而是一個結構體,最好稱它爲一個結構體。

新的代碼也可以是這樣的:

Number& Number::operator=(const Number& n) 
{ 
    destroy(); 
    for(Node* current = gg1.start; current; current = current->next) 
    add(current->value); 
} 

void Number::destroy() 
{ 
    Node* temp; 
    for(Node* current = start; current; current = current->next, delete temp) 
     temp = current; 
    start = NULL; 
    end = NULL; 
} 
+0

非常感謝您的答案。儘管複製功能的唯一問題是它不會按預期「重製」列表,而是以某種方式添加到當前列表中,至少這是我通過測試得到的結果。我必須承認我仍然是C++的初學者。那麼,至少我更接近解決這個問題。 – user1939088

+0

NP,您可以觀察到「添加」,因爲您在destroy()的末尾沒有將開始和結束設置爲NULL。 –

+0

那麼,現在的問題是,雖然我已經糾正了這個錯誤,但我仍然從斐波那契函數中得到奇怪的結果(我添加了一個for循環)。當我讓它計算f.e.時,不要給我一大堆數字。第10個數字給了我很多節點,其中只有1個數字。我想我可能在功能上犯了另一個錯誤,儘管我也看不到這一個。 (這只是一個循環,有1個加法和2個拷貝) – user1939088