Visual C ++调试断言失败?

时间:2016-01-27 14:11:54

标签: c++ templates visual-c++ smart-pointers

在下面的代码中实现了一个执行正常的智能指针,但最后我得到以下消息:

enter image description here

以下是代码:

smart_ptr.h

#ifndef SMART_PTR_H
#define SMART_PTR_H

/*
    Class: Auto_ptr

    It implements a generic
    smart pointer that doesn't need
    to be deleted explicitly, i.e.
    it provides garbage collection.
*/
template<class T>
class Auto_ptr{
public:
    // constructors
    explicit Auto_ptr(T* p = nullptr): value(p) { };    // constructor
    Auto_ptr(Auto_ptr& p);                      // copy constructor
    Auto_ptr& operator= (const Auto_ptr& p);            // copy assignment
    ~Auto_ptr() { std::cout << "pointer deleted\n"; delete value; }                     // destructor

    // access operators
    const T& operator* () const { return *value; }      // dereference operator
    const T* operator->() const { return value; }       // indirect class member access (arrow) operator

    // non-modifying members
    T* get() { return value; }                          // getter method
    void reset(T* v);                                   // reassing new value(default value: nullptr)
    T* release();                                       // transfers the object to another pointer; without destroying it
private:
    // data member
    T* value;

};

//--------------------------------------------------------------------------------------------------------
// class Auto_ptr member implementations
// Constructors
// copy constructor
template<class T>
Auto_ptr<T>::Auto_ptr(Auto_ptr& p) {
    value = p.release();
}

// copy assignment
template<class T>
Auto_ptr<T>& Auto_ptr<T>::operator= (const Auto_ptr& p ) {
    if (this == &p) return *this;
    if (value) delete value;
    value = p.value;
    return *this;
}

/*
    Function: release()
    Use: T ptr =  auto_ptr_obj.release();

    It transfers the pointer value to the
    caller, setting the data member value
    to nullptr.
*/
template <class T>
T* Auto_ptr<T>::release() {
    T* temp = value;
    value = nullptr;
    return temp;
}

/*
    Function: reset()
    Use: auto_ptr_obj.release(new_pointer);

    It deletes the object pointer to by
    pointer value and assings new_pointer; 
*/
template <class T>
void Auto_ptr<T>::reset(T* v) {
    delete value;
    value = v;
}   

#endif

main.cpp

#include <iostream>
#include "smart_ptr.h"
#include "assert.h"

//=====================================================================
void test1 () {
    std::cout <<"\nTest constructor and get() member.\n";
    Auto_ptr<int> p(new int);
    *p.get() = 5;
    std::cout <<"p points to: "<< *p << "\n";

    //assert(*p, 5);
    std::cout <<"TEST 1 DONE\n";
}

void test2 () {
    std::cout <<"\nTest reset() and release() members.\n";
    Auto_ptr<int> p(new int);
    *p.get() = 5;
    std::cout <<"p points to: "<< *p << "\n";

    p.reset(new int(10));
    std::cout <<"reset() p points to: "<< *p << "\n";
    //assert(*p, 10);

    int *temp = p.release();
    std::cout <<"caller of release(), temp points to: "<< *temp << "\n";
    //assert(*temp, 10);

    // nullptr dereferece error 
    // std::cout <<"p after being release()d points to: "<< *p << "\n";

    std::cout <<"TEST 2 DONE\n";
}

void test3 () {
    std::cout <<"\nTest copy constructor and copy assignment.\n";
    Auto_ptr<int> p1(new int(10));
    Auto_ptr<int> p2(p1);

    std::cout <<"copy constructed p2 points to: "<< *p2 << "\n";
    //assert(*p2, 10);

    Auto_ptr<int> p3(new int(20));
    p1 = p3;
    std::cout <<"copy assigned p1 points to: "<< *p1 << "\n";
    //assert(*p1, 20);

    std::cout <<"TEST 3 DONE\n";
}

//=====================================================================
int main () {
    test1 ();
    test2 ();
    test3 ();

    getchar();
}

有趣的是,Live example中的错误不可重复。

这条消息可能是什么原因?

1 个答案:

答案 0 :(得分:2)

这通常是“双重删除”的结果 - 在这种情况下,我怀疑这是你的副本分配。

您指定value = p.value;,并且两个副本都保持相同的值,并且都尝试删除它。

您基本上需要将指针从一个对象移动到另一个对象,就像复制构造函数一样。您还需要删除const