如果违反了会有什么后果
看一个例子:
#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 pointerProcess 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};
}