代码段中的内存泄漏

时间:2013-05-01 18:53:05

标签: c++ memory-leaks

我正试图粉碎我的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 个答案:

答案 0 :(得分:5)

您永远不会删除m_memo的析构函数中的Fibonacci

由于您将m_memo分配为数组,因此应使用delete[] m_memo删除

答案 1 :(得分:2)

以下是具有不可复制的Fibonacci类的工作代码。为什么不呢 你在构造函数中分配内存。尽可能使用RAII 并记住五法则。首先避免所有这一切 使用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&);
  */
};

答案 2 :(得分:1)

您正在m_memo分配setToFind

m_memo = new long int[value];

但您的destructor没有delete [] m_memo。您应该在m_memo初始化constructor,如果使用C ++ 11,则使用copy constructor禁用assignment operatordelete,使您的课程无法复制:< / p>

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

否则你可以将它们设为私有。如果你使用像std::vector这样的容器,那么你的生活就会简单得多。

答案 3 :(得分: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在矢量上应用所需的查找算法并定义自己的仿函数。