Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;对于离开作用域的对象,内存没有被回收-我束手无策_C++_Memory_Memory Management_Memory Leaks - Fatal编程技术网

C++ C++;对于离开作用域的对象,内存没有被回收-我束手无策

C++ C++;对于离开作用域的对象,内存没有被回收-我束手无策,c++,memory,memory-management,memory-leaks,C++,Memory,Memory Management,Memory Leaks,我遇到了无法识别的特定内存泄漏问题。记忆的碎片 在这种特殊情况下,所有对象都在堆栈上(尽管大多数对象确实在堆上创建了一些东西)。这些对象的寿命非常短,而且在大多数情况下,它们都是活在for循环中的。我不知道到底发生了什么,但他们堆积的尸体留在记忆中。我已经做了足够多的调试,以确定它们的创建(以及随后从内存中删除的失败)是造成内存浪费的原因 通过大量测试,我已经验证了调用构造函数的次数等于调用析构函数的次数。其中一个类是虚拟类,所以我确保它的析构函数是虚拟的(它是虚拟的)。Valgrind没有指出

我遇到了无法识别的特定内存泄漏问题。记忆的碎片

在这种特殊情况下,所有对象都在堆栈上(尽管大多数对象确实在堆上创建了一些东西)。这些对象的寿命非常短,而且在大多数情况下,它们都是活在for循环中的。我不知道到底发生了什么,但他们堆积的尸体留在记忆中。我已经做了足够多的调试,以确定它们的创建(以及随后从内存中删除的失败)是造成内存浪费的原因

通过大量测试,我已经验证了调用构造函数的次数等于调用析构函数的次数。其中一个类是虚拟类,所以我确保它的析构函数是虚拟的(它是虚拟的)。Valgrind没有指出任何内存泄漏。我不知道还能尝试什么。我几乎认为我遇到了一个编译器错误,但通常这意味着我错了

如果有人能帮助我,我将不胜感激

下面是我正在使用的基本类。我用C++重新生成了C++中的生成器的概念。它们几乎是我整个计划的关键:

/**
 * @file    generator.hpp
 * @brief   Macros and class to create generators
 *
 * @author  Adam Baxter
 * @version 2.0
 * @date    2012/07/11
 * @copyright 2012
 */

#ifndef apollo_generator_hpp_
#define apollo_generator_hpp_

/**
 * @brief A macro to define the beginning of a generator's operator() function
 */
#define $gen_start if(_line < 0) { _line = 0;} \
switch(_line) { case 0:;

/**
 * @brief A macro to define the end of a generator's operator() function
 */
#define $gen_stop  } _line = 0; return false;

/**
 * @brief A macro to yield the generator's current position and create that corrosponding return value
 */
#define $yield(R)    \
do { \
    _line = __LINE__; \
    generate(R); return true; case __LINE__:; \
} while (0);

namespace apollo {

/**
 * @class   Generator generator.hpp "generator.hpp"
 * @brief   Standard generator interface for all generators in this project.

     The macros above, coupled with this class, are used to define functions that can be jumped into and out at arbitrary positions

    Consider NumGen, a simple number generator:

    class NumGen : public Generator<int> {

    NumGen() : _i(0), Generator<int>() {}

    bool operator()(value_type &rv) {
        $gen_start;
        for(_i = 0; _i < 10; _i++) {
            $yield(rv);
        }
        $gen_stop;
    }

    void generate(value_type &rv) {
        rv = _i;
    }

    private:
        value_type _i;
    };

    NumGen is nothing more than a simple for-loop that yields numbers [0,10).
    The importance of the generator is to separate out the generator's next state calculation (_i++)
    from the return value's generator (rv = _i) from the rest of the application logic

    The more complex of a state we're working with, the more powerful this idea becomes. 

    @Note Successive calls to operator() will place execution directly after
        the last called yield statement
        - Any variable modification between $gen_start and $yield will be skipped! -
        A generator's state must be held in its member variables and care must be exercised when using 
        local variables in operator().
 */

template <typename T>
class Generator {
public:

    /**
     * The type the generator creates
     */
    typedef T value_type;

    // default ctor
    Generator(): _line(-1) {}

    // copy ctor
    Generator(Generator const &rhs) : _line(rhs._line) {}

    // move ctor
    Generator(Generator &&rhs) : _line(rhs._line) {}

    // copy = ctor
    Generator& operator=(Generator const &rhs)
    {
        if (this != &rhs) {
            _line = rhs._line;
        }
        return *this;
    }

    // move = ctor
    Generator& operator=(Generator &&rhs)
    {
        if (this != &rhs) {
            _line = rhs._line;
        }
        return *this;
    }

    /**
    * Generator calculates its next state, creates the value for that state.
    *
    * @param[in,out] rv The return value's storage location
    *
    * @return True if generator at next state and a new return value is generated. 
    *   False if there are no more valid states and return value is untouched.
    */
    virtual bool operator()(value_type &rv) = 0;

    /**
     * Using the generator's current state, create the return value
     *
     *  @param[in,out]  rv The return value's storage location
     */
    virtual void generate(value_type &rv) const = 0; 

    // == operator
    virtual bool operator==(Generator const &rhs) const {
        return _line == rhs._line;
    }

    // deconstructor
    virtual ~Generator() {}

protected:
    int _line; /**< The source code line $gen_start will use for its switch */
};

} /* namespace apollo */

#endif // apollo_generator_hpp_
/**
*@file generator.hpp
*@用于创建生成器的简短宏和类
*
*@作者亚当·巴克斯特
*@version 2.0
*@日期2012/07/11
*@版权所有2012
*/
#ifndef阿波罗水电站发电机_
#定义阿波罗发电机组水电站_
/**
*@brief宏定义生成器运算符()函数的开头
*/
#如果(_line<0){u line=0;}定义$gen_start\
开关(_线){情况0:;
/**
*@brief宏定义生成器运算符()函数的结尾
*/
#定义$gen\u stop}\u line=0;返回false;
/**
*@简要介绍一个宏,以生成生成器的当前位置并创建相应的返回值
*/
#定义美元收益率(R)\
做{\
_行=\uuuu行\uuuuu\
生成(R);返回true;大小写为行\
}而(0);
名称空间阿波罗{
/**
*@class Generator.hpp“Generator.hpp”
*@本项目所有发电机的简短标准发电机接口。
上面的宏加上这个类,用于定义可以在任意位置跳入和跳出的函数
想想NuMGEN,一个简单的数字生成器:
NumGen类:公共生成器{
NumGen():i(0),生成器(){}
布尔运算符()(值类型和rv){
$gen_start;
对于(_i=0;_i<10;_i++){
美元收益率(rv);
}
$gen_站;
}
无效生成(值类型和rv){
rv=_i;
}
私人:
值\类型\ i;
};
NumGen只不过是一个简单的for循环,可以生成数字[0,10]。
生成器的重要性在于分离出生成器的下一个状态计算(_i++)
来自应用程序逻辑其余部分的返回值生成器(rv=i)
我们工作的国家越复杂,这个想法就越强大。
@注意:对运算符()的连续调用将直接在
最后一个称为收益率声明
-将跳过$gen_start和$YILD之间的任何变量修改-
生成器的状态必须保存在其成员变量中,使用时必须小心
运算符()中的局部变量。
*/
样板
类生成器{
公众:
/**
*生成器创建的类型
*/
类型定义T值_类型;
//默认选择器
生成器():_行(-1){}
//复印机
发电机(发电机常数和rhs):_线(rhs._线){}
//移动驱动器
生成器(生成器和rhs):_line(rhs._line){}
//拷贝=ctor
发电机和操作员=(发电机常数和rhs)
{
如果(此!=&rhs){
_直线=右侧。_直线;
}
归还*这个;
}
//move=ctor
生成器和运算符=(生成器和rhs)
{
如果(此!=&rhs){
_直线=右侧。_直线;
}
归还*这个;
}
/**
*生成器计算其下一个状态,并为该状态创建值。
*
*@param[in,out]rv返回值的存储位置
*
*@如果生成器处于下一个状态并生成新的返回值,则返回True。
*如果没有更多有效状态且返回值未被触及,则为False。
*/
虚拟布尔运算符();
/**
*使用生成器的当前状态,创建返回值
*
*@param[in,out]rv返回值的存储位置
*/
虚拟空洞生成(值类型&rv)常数=0;
//==运算符
虚拟布尔运算符==(生成器常量和rhs)常量{
返回_行==rhs._行;
}
//解构器
虚拟~Generator(){}
受保护的:
int _line;/**<源代码行$gen_start将用于其开关*/
};
}/*阿波罗*/
#endif//apollo_发电机_水电站_

/**
*@file generatoriterator.hpp
*@brief使用生成器创建迭代器的类
*
*@作者亚当·巴克斯特
*@version 2.0
*@日期2012/07/11
*@版权所有2012
*/
#ifndef阿波罗发电站_
#定义阿波罗水电站发电机组_
#包括
#包括
#包括
名称空间阿波罗{
样板
类生成器迭代器:公共boost::迭代器<
发电机,
常量typename G::value\u type,
boost::前向遍历标记>{
公众:
G型发电机;
GeneratorIterator():_finished(true){}
显式生成器计算器(生成器常量和生成器):
_gen(gen),
_已完成(错误){
这个->操作符++();
}
显式生成器计算器(生成器和生成器):
_发电机(标准:正向(发电机)),
_已完成(错误){
这个->操作符++();
}
发电机致畸器(发电机致畸器常数和rhs):
_总工程师(右总工程师),
_已完成(rhs.\U已完成){
如果(!\u完成){
_发电机(rv);
}
}
发电机
/**
 * @file    generatoriterator.hpp
 * @brief   A class to create iterators out of generators
 *
 * @author  Adam Baxter
 * @version 2.0
 * @date    2012/07/11
 * @copyright 2012
 */

#ifndef apollo_generatoriterator_hpp_
#define apollo_generatoriterator_hpp_

#include <utility>
#include <iterator>
#include <boost/iterator/iterator_facade.hpp>

namespace apollo {

template <typename G>
class GeneratorIterator : public boost::iterator_facade <
    GeneratorIterator<G>,
    const typename G::value_type,
    boost::forward_traversal_tag> {
public:
    typedef G generator_t;

    GeneratorIterator() : _finished(true) {}

    explicit GeneratorIterator(generator_t const &gen) :
        _gen(gen),
        _finished(false) {
            this->operator++();
    }

    explicit GeneratorIterator(generator_t &&gen) :
        _gen(std::forward<generator_t>(gen)),
        _finished(false) {
            this->operator++();
    }

    GeneratorIterator(GeneratorIterator const &rhs) :
        _gen(rhs._gen),
        _finished(rhs._finished) {
            if (!_finished) {
                _gen.generate(_rv);
            }
        }

    GeneratorIterator(GeneratorIterator &&rhs) :
        _gen(std::move(rhs._gen)),
        _rv(std::move(rhs._rv)),
        _finished(rhs._finished) {}

    GeneratorIterator& operator=(GeneratorIterator const &rhs) {
        if (this != &rhs) {
            _gen = rhs._gen;
            _finished = rhs._finished;
            if (!_finished) {
                _gen.generate(_rv);
            }
        }
        return *this;
    }

    GeneratorIterator& operator=(GeneratorIterator &&rhs) {
        if (this != &rhs) {
            _gen = std::move(rhs._gen);
            _rv = std::move(rhs._rv);
            _finished = rhs._finished;
        }
        return *this;
    }

    generator_t const& gen() const {
        return _gen;
    }

    ~GeneratorIterator() {}

private:
    friend class boost::iterator_core_access;
    generator_t _gen;
    typename generator_t::value_type _rv;
    bool _finished;

    bool equal(GeneratorIterator const &rhs) const {
        if (_finished || rhs._finished) {
            if (_finished && rhs._finished) {
                return true;
            } else {
                return false;
            }
        }  else if ((_rv == rhs._rv) &&
            (_gen == rhs._gen)) {
            return true;
        }
        return false;
    }

    void increment() { advance(); }

    void advance(std::ptrdiff_t dist = 1) {
        while (!_finished && (dist > 0)) {
            if( _gen(_rv) == false) {
                _finished = true;
            }
            dist -= 1;
        }
    }

    std::ptrdiff_t distance_to(GeneratorIterator const &rhs) const {
        using std::distance;
        if (_finished && rhs._finished) {
            return 0;
        }
        if (!_finished) {
            return distance(*this, rhs);
        } else {
            return distance(rhs, *this) * -1;
        }
    }

    const typename generator_t::value_type& dereference() const { return _rv; }

};

template<class G, typename... Args>
GeneratorIterator<G> make_geniter(Args && ...args) {
    return GeneratorIterator<G>(G(std::forward<Args>(args)...));
}

} /* namespace apollo */

#endif /* apollo_generatoriterator_hpp_ */