简体   繁体   English

使用shared_ptr将原始指针传递给函数

[英]Passing raw pointer to a function with shared_ptr

When I have a function: 当我有一个功能:

void foo(std::shared_ptr<T> a, std::shared_ptr<T> b);

is there a chance of memory leak when calling it like this: 这样调用时是否有内存泄漏的可能:

foo(new T(), new T());

That won't compile since the conversion to shared_ptr is explicit. 由于向shared_ptr的转换是显式的,因此无法编译。 If I were to naively fix that: 如果我要天真地解决这个问题:

foo(std::shared_ptr<T>(new T()), std::shared_ptr<T>(new T()));  // don't do this

then there is indeed a chance of a memory leak. 那么确实有可能发生内存泄漏。 One allowed order of evaluation is: 允许的评估顺序为:

T * p1 = new T();
T * p2 = new T();
std::shared_ptr<T> s1(p1);
std::shared_ptr<T> s2(p2);
foo(s1,s2);

If the second new throws an exception, then the first object would be leaked. 如果第二个new抛出异常,则第一个对象将被泄漏。 To fix this, make sure the first shared pointer is initialised before attempting the second allocation, either with a temporary variable: 要解决此问题,请在尝试使用临时变量进行第二次分配之前,确保第一个共享指针已初始化:

std::shared_ptr<T> a(new T());
std::shared_ptr<T> b(new T());
foo(a,b);

or calling a function to initialise each 或调用一个函数来初始化每个

foo(std::make_shared<T>(), std::make_shared<T>());

As @Mike said, your source won't compile. 正如@Mike所说,您的源代码不会编译。 You need an explicit construction of shared_ptr , such as: 您需要显式构造shared_ptr ,例如:

foo(std::shared_ptr<T>(new T()), std::shared_ptr<T>(new T()));

It's still unsafe. 还是不安全的。 In c++ expressions used as function arguments may generally be evaluated in any order, including interleaved, except as otherwise restricted by the other rules. 在c ++表达式中,用作函数参数的表达式通常可以按任何顺序进行求值,包括插入,除非受其他规则限制。

For one example, the order may be: 例如,顺序可能是:

  1. allocate memory for the first T 为第一个T分配内存
  2. construct the first T 构造第一个T
  3. allocate memory for the second T 为第二个T分配内存
  4. construct the second T 构造第二个T
  5. construct the shared_ptr 构造shared_ptr
  6. construct the shared_ptr 构造shared_ptr

And if step(3) or (4) failed (by throwing), The object constructed at step(2) will not be destructed, and memory allocated at step(1) will leak. 如果步骤(3)或(4)失败(通过抛出),则不会破坏在步骤(2)构造的对象,并且在步骤(1)分配的内存将泄漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM