0

私は自分の C++ を払いのけようとしています。メモ化を使ってフィボナッチ数列を見つける簡単なプログラムを作成しました。メモリリークがあり、その理由がわかりません。リークは Fibonacci::setToFind で報告されます。

長いコードチャンクで申し訳ありませんが、より最小限の再現可能な例を作成する方法がわかりませんでした.

#include <iostream>

class Fibonacci
{
public:
    int m_valuefound;
    int m_tofind;
    long int *m_memo;

    int findValue(int value){
        if (m_memo[value] == 0) {
            if (value == 0 || value == 1) {
                m_memo[value] = 1;
            } else {
                m_memo[value] = findValue(value-1) + findValue(value-2);
            }
        }
        return m_memo[value];
    }

    void setToFind(int value){
        m_tofind = value;
        m_memo = new long int[value];

        std::fill_n(m_memo,value,0);
    }

    void solve(){

        int value = m_tofind;
        int result = findValue(value);

        std::cout<< "Value is: " << result << std::endl;
    }

    ~Fibonacci(){};


};

int main (int argc, char * const argv[]) {
    std::cout << "Enter integer values until you'd like to quit.  Enter 0 to quit:";

    int user_ind=0;

    // for testing non-interactivly
    while(true){
    for (user_ind=1; user_ind<45; user_ind++) {
        Fibonacci *test = new Fibonacci;
        test->setToFind(user_ind);
        test->solve();
            delete test;
    }

    }

    return 0;
}
4

4 に答える 4

5

m_memoのデストラクタで削除することはありませんFibonacci

m_memo を配列として割り当てているため、次のように削除する必要がありますdelete[] m_memo

于 2013-05-01T18:55:32.937 に答える
2

Fibonacciこれは、コピー不可能なクラスを使用した作業コードです。コンストラクターでメモリを割り当ててみませんか。可能な限り RAII を使用し、5 つのルールを覚えておいてください。を使用して、これらすべてを最初から回避しstd::vectorます。

#include <iostream>

class Fibonacci
{
public:
    int m_valuefound;
    int m_tofind;
    long int *m_memo;

    int findValue(int value){
        if (m_memo[value] == 0) {
            if (value == 0 || value == 1) {
                m_memo[value] = 1;
            } else {
                m_memo[value] = findValue(value-1) + findValue(value-2);
            }
        }
        return m_memo[value];
    }

    void setToFind(int value){
        m_tofind = value;
        m_memo = new long int[value];

        std::fill_n(m_memo,value,0);
    }

    void solve(){

        int value = m_tofind;
        int result = findValue(value);

        std::cout<< "Value is: " << result << std::endl;
    }

  // why don't you allocate in the constructor?
  Fibonacci() : m_valuefound(0), m_tofind(0), m_memo(nullptr) {}

  ~Fibonacci() {
    delete[] m_memo;
  };
  // make the class non-copyable
  Fibonacci(const Fibonacci&) = delete;
  const Fibonacci& operator=(const Fibonacci&) = delete;
  /*
    C++03 non-copyable emulation
private:
  Fibonacci(const Fibonacci&);
  const Fibonacci& operator=(const Fibonacci&);
  */
};
于 2013-05-01T18:59:41.283 に答える
1

に割り当てm_memoていsetToFindます:

m_memo = new long int[value];

しかし、あなたにdestructorは がありませんdelete [] m_memo。C++ 11を使用している場合は、を無効にして使用することにより、クラスを初期化m_memoし、constructorクラスをコピー不可にする必要があります。copy constructorassignment operatordelete

Fibonacci(const Fibonacci&) = delete;
const Fibonacci& operator=(const Fibonacci&) = delete;

それ以外の場合は、それらを非公開にすることができます。あなたの人生のようなコンテナを使用した場合は、std::vectorはるかに簡単になります.

于 2013-05-01T18:58:18.380 に答える
0

STLアルゴリズムをもっと使うことをお勧めします。これは、最適化されていないファンクターを使用したコード スニペットですが、STL の威力を理解することができます。

#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

class Fibonacci
{
public:
    Fibonacci();
    ~Fibonacci() {}

    int operator()();
private:
    int n0_;
    int n1_;
    int n_;
};

Fibonacci::Fibonacci():n0_(0),n1_(1),n_(0)
{
}

int Fibonacci::operator()()
{
    if(n_ > 1)
        return (++n0_) + (++n1_);
    else
        return ++n_;
}

using namespace std;
int main()
{
    Fibonacci func;
    vector<int> v;

    //generate 100 elements
    generate_n(v.begin(),100,func);

    //printing the values using a lambda expression
    for_each(v.begin(),v.end(),[](const int val){cout << val << endl;});

    return 0;
}

find_if次に、独自のファンクターを使用および定義して、必要な検索アルゴリズムをベクターに適用できます。

于 2013-05-01T22:23:51.643 に答える