深度理解:多个auto_ptr同时引用同一个资源对象下的释放问题及赋值问题

深度理解:多个auto_ptr同时引用同一个资源对象下的释放问题及赋值问题

作者:BlogUpdater |  时间:2017-04-29 |  浏览:2325 |  评论已关闭 条评论

首先说一句,auto_ptr已经在C++ 11中已经标注为Deprecated,也即你可以继续使用这玩意,但是在C++持续的演进中,这玩意将慢慢不被主流编译器支持。”Deprecated”,说白了,就是我们在将来可能不支持这个了,现在你可以继续使用,编译器也将继续可以编译通过,趁现在有时间,请尽早使用其他改进方法吧。

1. 多个auto_ptr引用同一个资源对象
下面看一段代码,以下代码演示了什么叫做:Undefined behavior。

void TestPtr(int * p)
{
    auto_ptr<int> ptr2(p);
    int temp2 = *ptr2;
}

int main()
{
    int * p = new int;
    *p = 100;
    auto_ptr<int> ptr1(p);
    int temp1 = *ptr1;

    TestPtr(p);

    return 0;
}

ptr1首先持有了资源p的引用,在ptr1离开作用域(即main函数)时,会在其析构函数中自动释放掉资源p,一切是那么顺畅。但是,在函数TestPtr中,ptr2也持有了同一个资源对象p的引用,虽然以上代码中temp1和temp2的值都能正常获取且都为100,但是在ptr2先于ptr1离开作用域,ptr2离开作用域触发了第一次资源释放。ptr1离开main函数后,随即触发同一资源的第二次释放,在这种情况下,代码的行为就是文档中所谓的:Undefined behavior。在实际开发过程中,在这种行为发生时,出现了线程参数传递的异常情况:即线程参数首先在heap上创建,然后传送给线程过程,在线程过程中尝试获取该参数时,发现该参数已经被销毁。

2. 关于auto_ptr赋值过程中的资源控制权转移
观察以下代码:

int * p = new int;
*p = 100;

auto_ptr<int> ptr1(p);
auto_ptr<int> ptr2 = ptr1;

int temp2 = *ptr2;
int temp1 = *ptr1;    // auto_ptr can not dereference

ptr1首先持有资源p,然后将ptr1赋值给ptr2,注意,此赋值之后,ptr2持有资源p,ptr1被设置为empty,也即完成了资源p的控制权从ptr1到ptr2的转移。下面的代码对ptr1进行dereference时,就会出现空指针解除引用内存违规。

标签:

评论已关闭。