环境:Win10 x64, VS2017
描述:智能指针错误使用后,所指对象被释放
代码:
#include <iostream>
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include <map>
class People
{
public:
People()
{
std::cout << "构造" << std::endl;
}
~People()
{
std::cout << "析构" << std::endl;
}
void SetValue()
{
contents.push_back(1);
contents.push_back(2);
contents.push_back(3);
}
private:
std::vector<int> contents;
};
struct PeopleCollection
{
std::map<int, People*> m_data;
};
void GetPeople(std::shared_ptr<People> &people)
{
//people contents 赋值成功
people->SetValue();
}
void GetPeopleCollection(PeopleCollection &data)
{
//创建智能指针,并赋值
std::shared_ptr<People> peoplePtr = std::make_shared<People>();
GetPeople(peoplePtr);
//将智能指针所指向对象存储
data.m_data[1] = peoplePtr.get();
} //当函数结束时,因为 peoplePtr 引用计数为0,所以所指向对象内存被释放,导致data.m_data[1] 数据无效
int main()
{
PeopleCollection peopleCollection;
GetPeopleCollection(peopleCollection);
People* people = peopleCollection.m_data[1];
}
解决办法: 修改成std::map<int, std::share_ptr<People> m_data;
下面样例也是错误的:
#include <iostream>
#include <algorithm>
#include <memory>
#include <string>
#include <vector>
#include <map>
class People
{
public:
People()
{
std::cout << "构造" << std::endl;
}
~People()
{
std::cout << "析构" << std::endl;
}
void SetValue()
{
m_contents.push_back(1);
m_contents.push_back(2);
m_contents.push_back(3);
}
private:
std::vector<int> m_contents;
};
void GetPeople(People *people)
{
People tmpPeople;
tmpPeople.SetValue();
//tmpPeople为临时对象,函数结束时被释放,people指向对象被清空
people = &tmpPeople;
}
int main()
{
People* tmpPeoplePtr = new People();
GetPeople(tmpPeoplePtr);
return 0;
}
总结:在使用智能指针或指针时,一定要注意临时变量的有效范围,否则数据会被清空!!!