双重免费或腐败,为什么会出现?

时间:2015-11-01 15:54:41

标签: c++ pointers smart-pointers double-free

我几乎完成了我的智能指针(我知道......)所以我将它上传到我的大学网站,该网站对我的代码运行了大量自动化测试。许多测试有两个问题:

  • 超出内存或时间限制
  • 内存访问问题(即空指针)

问题是我不知道正在进行什么样的测试。我能够阅读自动化测试'我做过的stdout,写在那里:

<div class="row content-container">

            <div class="col-md-9" id="map-content">
            <h1>#Map</h1>

        </div> <!-- MAP -->

        <div class="col-md-3" id="route">
        <h1>#Route</h1>
        </div> <!-- Route -->

        <div class="col-md-9" id="breadcrumbs">
        </div> <!-- Breadcrumbs -->


    </div> <!--Row Content--> 

所以我猜错了一些奇怪的原因,它不会调用我的my_pointer()构造函数? 这是我的智能指针类:

In instantiation of ‘my_pointer<T>::my_pointer() [with T = tester]’:
error: no matching function for call to ‘tester::tester()’
note: candidates are:
tester::tester(my_pointer<tester>)
candidate expects 1 argument, 0 provided
tester::tester(const tester&)
candidate expects 1 argument, 0 provided

这是一个类,可以计算引用:

template<class T>
class my_pointer {
    T* raw_pointer;

public:
    my_pointer() {
        raw_pointer = new T();
        raw_pointer->incRefCnt();
    }

    my_pointer(T *obj) : raw_pointer(obj) {
        if(raw_pointer != NULL) raw_pointer->incRefCnt();
    }

    my_pointer(const my_pointer<T>& smart_pointer) : raw_pointer(smart_pointer.raw_pointer) {
        if(raw_pointer != NULL) raw_pointer->incRefCnt();
    }

    T& operator*() {
        return *raw_pointer;
    }

    T* operator->() {
        return raw_pointer;
    }

    operator T*() {
        return raw_pointer;
    }

    my_pointer<T> &operator=(const my_pointer<T> &smart_pointer) {
        if(this != &smart_pointer && raw_pointer != NULL) {
            /** if this was the last reference to the given memory address */
            if (raw_pointer->decRefCnt() == 0) {
            delete raw_pointer;                    
            }

            raw_pointer = smart_pointer.raw_pointer;
            raw_pointer->incRefCnt();
        }

        return *this;
    }

    bool operator== (const T* pointer) {
        return raw_pointer == pointer;
    }

    bool operator!= (const T* pointer) {
        return raw_pointer != pointer;
    }

    bool operator== (const my_pointer<T> &smart_pointer) {
        return raw_pointer == smart_pointer.raw_pointer;
    }

    bool operator!= (const my_pointer<T> &smart_pointer) {
        return raw_pointer != smart_pointer.raw_pointer;
    }

    ~my_pointer() {
       if(raw_pointer->decRefCnt() == 0 && raw_pointer != NULL) {
           delete raw_pointer;
        }
    }
};

你能看到代码有什么问题吗?提前谢谢!

2 个答案:

答案 0 :(得分:3)

您无条件地在析构函数中删除原始指针。这是错的。您必须减少引用计数,并且只有在它变为零时才删除。

您还可以在多个地方致电raw_pointer->incRefCnt();,而无需检查raw_pointer是否为NULL

答案 1 :(得分:0)

我在你的代码中看到两个问题:

  1. 在operator =()中:在您已取消引用if(raw_pointer != NULL)后(在上面一行),您会检查raw_pointer。你应该反转支票。

  2. 在析构函数中:您不应该先调用decRefCnt(),如果引用计数已降为零,则只删除raw_pointer吗?

  3. 由于operator=()~my_pointer()中的代码实际上需要相同的代码来减少引用计数并在需要时删除raw_pointer(AFAICS),因此将该功能提取到新方法和从两个地方打电话。