3

似乎 std::auto_ptr 和分配有问题,以至于引用的对象似乎由于某种原因被丢弃了。

std::auto_ptr<AClass> someVar = new AClass();  // should work, but mangles content
std::auto_ptr<AClass> someVar( new AClass() ); // works fine.
std::auto_ptr<AClass> someVar = std::auto_ptr<AClass>(new AClass()); // works fine.

std::auto_ptr<AClass> someVar;
someVar.reset( new AClass() ); // works fine.

我已经对其进行了跟踪,并且似乎(通过观察调试器中的值)问题发生在从临时 std::auto_ptr_byref() 传输指针时,该临时 std::auto_ptr_byref() 是为包装 rhs 指针而创建的。也就是说进入auto_ptr(auto_ptr_ref<_Ty> _Right)函数时_Right中的值是正确的,但是离开时_Myptr中的值是垃圾。

template<class _Ty>
    struct auto_ptr_ref
        {   // proxy reference for auto_ptr copying
    auto_ptr_ref(void *_Right)
        : _Ref(_Right)
        {   // construct from generic pointer to auto_ptr ptr
        }

    void *_Ref; // generic pointer to auto_ptr ptr
    };

template<class _Ty>
class auto_ptr
    {   // wrap an object pointer to ensure destruction
public:
typedef _Ty element_type;

explicit auto_ptr(_Ty *_Ptr = 0) _THROW0()
    : _Myptr(_Ptr)
    {   // construct from object pointer
    }

auto_ptr(auto_ptr<_Ty>& _Right) _THROW0()
    : _Myptr(_Right.release())
    {   // construct by assuming pointer from _Right auto_ptr
    }

auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
    {   // construct by assuming pointer from _Right auto_ptr_ref
    _Ty **_Pptr = (_Ty **)_Right._Ref;
    _Ty *_Ptr = *_Pptr;
    *_Pptr = 0; // release old
    _Myptr = _Ptr;  // reset this
    }
auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty> _Right) _THROW0()
{   // assign compatible _Right._Ref (assume pointer)
_Ty **_Pptr = (_Ty **)_Right._Ref;
_Ty *_Ptr = *_Pptr;
*_Pptr = 0; // release old
reset(_Ptr);    // set new
return (*this);
}

起初我以为它搞砸了继承并切断了接口,但是即使该类只有一个父类也会发生这种情况。

如果我们记得的话,我们可以避免做 = new,或者通过使用方括号或更改为在 rhs 上具有显式 std::auto_ptr temp,这当然容易出错。

只是这个版本的库被破坏了,还是我没有得到一些底层的东西?

我们还注意到将 std::auto_ptr 分配给 boot::shared_ptr 的类似问题,尽管我们现在完全删除了它,我不记得是哪种语法导致了这个问题。

4

3 回答 3

10

第一行:

std::auto_ptr<AClass> someVar = new AClass();  // should work, but mangles content

应该会导致编译器错误。因为没有从原始AClass指针到 an的隐式转换auto_ptr(带有原始指针的 an 的构造函数auto_ptr被标记为explicit),所以不允许使用“复制初始值设定项”形式进行初始化。

VC9 给出以下错误:

C:\temp\test.cpp(23) : error C2440: 'initializing' : cannot convert from 'AClass *' to 'std::auto_ptr<_Ty>'

我尝试过的其他编译器(GCC 3.4.5、Comeau C/C++ 4.3.10.1、Digital Mars)给出了类似的错误。

编辑:

看起来这实际上是 VS2005 实现中的一个错误auto_ptr<>(不确定它是在 SP1 中引入还是从一开始就在 VS2005 中)在 VS2008 中得到修复。这是该问题的 MS Connect 错误记录:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842&wa=wsignin1.0

于 2009-01-09T07:01:56.670 回答
4

VC6 和 VC9 之间的 VC++ 中的已知错误:http ://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842

于 2009-01-09T09:05:17.437 回答
0

编辑:迈克尔说得很对,这是一个编译错误,那么您使用的是哪个编译器?您需要调用reset以将新值放入 auto_ptr。

于 2009-01-09T06:57:55.430 回答