[咬文嚼字学C++]用来初始化智能指针的普通指针必须指向动态内存

如果违反了会有什么后果

看一个例子:

#include <iostream>
#include <memory>
int main(int argc, char **argv){
    int x = 10;
    std::shared_ptr<int> spi{&x};
    std::cout << *spi << std::endl; //10
    std::cout << "use_count:" << spi.use_count() << std::endl;//1

    return 0;
}

上面的例子中,直接用局部变量x的地址来初始化一个智能指针spi。x 和spi本身都是分配在栈上的,因此,当程序执行完之后,main函数退出的时候,会自动释放这两个对象的内存。对于spi来说,执行其析构函数,在析构函数中递减其所指向内存的引用计数,如果递减后引用计数变为0,则释放所关联的内存。因为只有一个共享指针指向这块内存,因此引用计数为1,递减后为0,释放其所指的内存(x的内存)。spi的析构函数执行完之后,继续调用x的“析构函数”,因为x是内置类型, 因此调用底层的free来释放其内存。这就导致一块内存被释放了两次。

程序输出:

10
use_count:1
free(): invalid pointer

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

 这种错误很少有人会犯,但有时候没那么明显的时候也许会有人犯这个错:

比如,将一个局部变量的地址传给一个接受std::shared_ptr的函数

void foo(std::shared_ptr<int> spi){

}
//......
int x = 10;
foo(std::shared_ptr<int>(&x));

或者,从一个返回std::shared_ptr的函数返回一个局部对象的地址:

std::shared_ptr<int> bar(){
    int x = 20;
    return std::shared_ptr<int>{&x};
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值