0

二重連結リストを使用して N 番目のフィボナッチ数を計算する関数を作成しようとしていますが、何らかの理由でコンパイルして実行すると連結リストの成長が止まりません。

これは 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 が表示されます。数値クラスは、単純な二重リンク ポインター リストです。

追加機能スタンドアロンは問題なく機能し、コピーも同様です。実際、これまではすべて正常に機能していました。関数を for ループで終了するのは簡単ですが、このエラーが原因でそうすることができません。誰かが私の間違いを知っていますか? 前もって感謝します。

4

1 に答える 1

0

delete現在、各ノードで呼び出すとdestroy()メモリが NULL アウトされず、メモリが解放されているとマークされるだけなので、無効なメモリ アクセスがあります。

推奨される修正:

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=、 の代わりに使用することをお勧めしますcopy。またはにcopyすることができます。関数の呼び出しはあいまいです。copy_fromcopy_tocopy
  • 可能な場合は常に 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;
}
于 2012-12-31T07:42:22.347 に答える