Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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 Leaks_Reference Counting - Fatal编程技术网

C++ 使用C+实现引用计数+;

C++ 使用C+实现引用计数+;,c++,memory-leaks,reference-counting,C++,Memory Leaks,Reference Counting,我正在研究我的数字信号处理框架。为了提供数据交换接口,我将所有缓冲区包装在一个数据类中,该类具有基于引用计数的GC机制(该系统足够简单,因此我相信ref-count可以处理这个问题) 它的工作原理如下: 构造数据实例时,它将其ref count设置为零 当实例被分派到N个DSP模块时,将N添加到其ref计数中 当DSP模块完成实例时,它会减少ref计数 当ref计数减少到零时,它删除此项 但是我发现我的程序中有内存泄漏 为了调试,我向数据类添加了静态变量m_alloccount和m_freeco

我正在研究我的数字信号处理框架。为了提供数据交换接口,我将所有缓冲区包装在一个数据类中,该类具有基于引用计数的GC机制(该系统足够简单,因此我相信ref-count可以处理这个问题)

它的工作原理如下:

  • 构造数据实例时,它将其ref count设置为零
  • 当实例被分派到N个DSP模块时,将N添加到其ref计数中
  • 当DSP模块完成实例时,它会减少ref计数
  • 当ref计数减少到零时,它删除此项
  • 但是我发现我的程序中有内存泄漏

    为了调试,我向数据类添加了静态变量m_alloccount和m_freecount,以记录分配和释放的时间。然后我在随机时间暂停执行,只发现这两个数字之间只有细微的差别

    例如,在不同的试验中:

    Trial         1   2    3      4
    m_alloccount  12  924  34413  364427
    m_freecount   11  923  34412  364425
    
    但事实是,内存使用量仍在增长。我相信所有内存分配都绑定到数据类。我现在真的想不出原因

    int Data::m_alloctime=0;
    int Data::m_freetime=0;
    
    Data::Data(DataPinOut*parent, int type, int size)
    :m_ptr(NULL)
    ,m_parent(parent)
    ,m_refcnt(0)
    ,m_type(type)
    ,m_size(size)
    {
        if(size>0)
            m_ptr=new char[TypeSizeLookup()*size];
        m_alloctime++;
    }
    
    Data::~Data()
    {
        delete [] (char*)m_ptr;
        m_freetime++;
    }
    
    void Data::Delete()
    {
        std::lock_guard<std::mutex>*lock=new std::lock_guard<std::mutex>(m_mutex);
    
        if(m_refcnt>1)
        {
            m_refcnt--;
            delete lock;
        }
        else
        {
            delete lock;
            delete this;
        }
    }
    
    int Data::m_alloctime=0;
    int Data::m_freetime=0;
    数据::数据(数据输出*父级,整数类型,整数大小)
    :m_ptr(空)
    ,m_家长(家长)
    ,m_refcnt(0)
    ,m_类型(类型)
    ,m_尺寸(尺寸)
    {
    如果(大小>0)
    m_ptr=新字符[TypeSizeLookup()*size];
    m_alloctime++;
    }
    数据::~Data()
    {
    删除[](字符*)m_ptr;
    m_freetime++;
    }
    void Data::Delete()
    {
    std::lock\u guard*lock=新std::lock\u guard(m\u互斥体);
    如果(m_refcnt>1)
    {
    m_refcnt--;
    删除锁;
    }
    其他的
    {
    删除锁;
    删除此项;
    }
    }
    
    根据我的经验,不管内部操作的数量有多大,只有一两个内存泄漏表示输入或输出变量泄漏。检查系统外部接口的记帐一致性

    std::shared_ptr
    很好,因为作为标准,它自动适合作为外部接口。用户可以与ref计数的对象交互,而不知道由
    DSP
    定义的管理细节


    除此之外,我们无法凭直觉了解您的程序中发生了什么。

    您如何维护计数器?如果计数器减量/测试不是原子的,则可能会泄漏减量,这将阻止对象达到0的refcount。

    步骤2。发送时添加n个引用


    是否保证发送模块?根据您的简单算法语句,未调度的已创建模块没有减少和删除其引用计数的机制。

    您使用过
    valgrind
    ?这是多线程的吗?请交出
    std::shared_ptr
    ,您自己不用担心计数。您看过
    std::shared_ptr
    了吗,C++11中的标准引用计数功能?@babel92您能告诉我们您是如何确定内存泄漏的吗?谢天谢地,如果他在随机的时间停下来,这些数字其实并不意味着什么——差异可能只是当时的活体。我更怀疑的是,他是如何确定这是内存泄漏的,而这可能是碎片并没有导致内存返回etc@imsoconfused我猜想他发布的试验表是从输入到最终输出的完整操作。但他很可能只是在处理最终输出对象之前打印统计数据。这可能被认为是一个错误,也可能不被认为是一个错误。不,他在问题中说,“然后我在随机时间暂停执行,只发现两个数字之间有细微的差异。”@imsoconfused,是的,但这可能与试验不同。我可能错了。哦,是的,这是另一种解释。我只是使用“英特尔VTune/Inspector”并切中要害,我使用std::lock_guard和互斥来保护与ref count操作相关的每个函数。是的。每个块的线程等待其所有输入引脚加载,然后执行其工作。之后,它减少了输入数据的引用计数。并且没有任何故障路径会导致数据实例不一致?不太可能,因为在我的测试示例中,只有三个块。。。A--> B-> C…回到COM的旧时代,在共享PTR等之前,REF计数泄漏最常见的原因是错误条件下的错误的DERFF,因此可能会考虑一些事情,因为这听起来像是在显式地管理。祝你好运。