简体   繁体   English

在共享指针中捕获内存泄漏?

[英]Catching a memory leak in a shared pointer?

Title pretty much says it all, I'm almost positive it's either in the copy constructor or the assignment operator, and I'm pretty sure it's the latter. Title几乎说明了一切,我几乎可以肯定,它是在复制构造函数中还是在赋值运算符中,而且我很确定它是后者。 It's a pretty short class, so I'll post the entire thing, any advice on how to handle it would be good. 这是一个很短的课程,所以我将发布整个内容,关于如何处理它的任何建议都是很好的。 I'm honestly a bit over my head here too, so any pointing to some solid reading would be greatly appreciated. 老实说,我在这里也有点不知所措,因此,任何指向可靠阅读的指导都将不胜感激。

#pragma once

//for non-learning purposes, boost has a good smart pointer
template <class type>
class sPtr
{
private:
    type *p;
    int r; //referenceCount

    void add()
    {
        r++;
    }
    int release()
    {
        return --r;
    }
public:
    sPtr(): p(NULL), r(1) {}
    sPtr(type *pValue): p(pValue)
    {
        add();
    }
    sPtr(const sPtr<type> & sp): p(sp.p), r(sp.r)
    {
        add();
    }
    ~sPtr()
    {
        if(release() == 0)
        {
            delete p;
        }
    }

    type* get()
    {
        return p;
    }

    type& operator*()
    {
        return *p;
    }
    type* operator->()
    {
        return p;
    }
    sPtr<type>& operator=(sPtr<type> sp)
    {
        std::swap(this->p, sp.p);
        std::swap(this->r, sp.r);
        add();

        return *this;
    }
};

I'm pretty sure that the assignment operator should be passed by reference, but I'm not sure on how this will affect the implementation. 我很确定应该通过引用传递赋值运算符,但是我不确定这将如何影响实现。 I tried a few different implementations and all of them still had the leak. 我尝试了几种不同的实现,但所有实现仍然存在泄漏。

Each of your shared pointers keeps track of its own separate reference count. 您的每个共享指针都跟踪其自己的独立引用计数。 This is obviously no good. 这显然是不好的。 When one is destroyed, the ref count on the others is not updated. 当一个销毁时,其他编号的引用计数不会更新。 You need to keep the reference count in a separate location that all the shared pointers have access to. 您需要将引用计数保留在所有共享指针均可访问的单独位置。

In addition to what Ben already mentioned, you are starting your reference count at 1 in your default constructor (and not initializing it at all in your others). 除了Ben已经提到的内容之外,您还需要在默认构造函数中将引用计数从1开始(而不是在其他构造函数中完全对其进行初始化)。 If you assign a pointer to it after the default constructor, your reference count would be 2, and when you call release, back to 1. In short, the only time your reference count would be 0 (indicating you can delete the object) is if you call release 1 more time than add was called. 如果在默认构造函数之后分配一个指向它的指针,则您的引用计数将为2,并且在调用release时返回1。总之,您的引用计数只有0(指示您可以删除该对象)的时间是如果您呼叫版本1的时间比呼叫add的时间长。 Typically, you want those calls to be symmetrical (call to add corresponds to call to release). 通常,您希望这些调用是对称的(添加调用对应于释放调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM