当我有一个功能时:
void foo(std::shared_ptr<T> a, std::shared_ptr<T> b);
在调用它时可能会发生内存泄漏:
foo(new T(), new T());
答案 0 :(得分:7)
由于转换为shared_ptr
是明确的,因此无法编译。如果我天真地解决这个问题:
foo(std::shared_ptr<T>(new T()), std::shared_ptr<T>(new T())); // don't do this
然后确实存在内存泄漏的可能性。一个允许的评估顺序是:
T * p1 = new T();
T * p2 = new T();
std::shared_ptr<T> s1(p1);
std::shared_ptr<T> s2(p2);
foo(s1,s2);
如果第二个new
抛出异常,那么第一个对象将被泄露。要解决此问题,请确保在尝试第二次分配之前初始化第一个共享指针,使用临时变量:
std::shared_ptr<T> a(new T());
std::shared_ptr<T> b(new T());
foo(a,b);
或调用函数初始化每个
foo(std::make_shared<T>(), std::make_shared<T>());
答案 1 :(得分:2)
正如@Mike所说,你的来源不会编译。您需要明确构造shared_ptr
,例如:
foo(std::shared_ptr<T>(new T()), std::shared_ptr<T>(new T()));
它仍然不安全。在c ++中,用作函数参数的表达式通常可以按任何顺序进行计算,包括交错,除非另有规则限制。
举个例子,订单可能是:
如果步骤(3)或(4)失败(通过抛掷),步骤(2)中构造的对象将不被破坏,并且步骤(1)中分配的内存将泄漏。