将共享_ptr作为指针指向指针

Pass shared_ptr as pointer to pointer

本文关键字:指针 共享 ptr      更新时间:2023-10-16

i具有C函数,其签名为

ldap_initialize LDAP_P((LDAP **ldp, LDAP_CONST char *url ));

我像这样使用

LDAP *ld;
ldap_initialize(&ld, "host_name");

它可以正常工作。

我想将LD更改为这样的共享指针。

  std::shared_ptr<LDAP> ldap(ld, [](LDAP * ld){ ldap_unbind(ld); });

并传递到ldap_initialize。

ldap_initialize(&ldap.get(), "host_name");

,但以上代码不起作用。是否有任何方法将共享_pointer或unique_ptr作为C样式指针转换为指针。

您将其倒退。您初始化一个原始指针并将其传递给std::shared_ptr进行管理:

auto get_shared_ldap(char const* url) {
  LDAP *ld;
  ldap_initialize(&ld, url);
  if (/*error occured*/) {
    // Consider throwing something
    return std::shared_ptr<LDAP>{};
  }
  return std::shared_ptr<LDAP>(ld, [](LDAP * ld){ ldap_unbind(ld); });
}

您无法分配给std::shared_ptr的内部状态。这是您要在代码样本中尝试做的。

您正在做的事情不起作用,因为ldap_initialize(从我能告诉的)使用指针参数返回值。但是shared_ptr.get()返回ld*。请注意,这是托管指针的副本,而不是对其的引用。因此,&ldap.get()行试图将地址置于临时,正确失败。shared_ptr无法提供参考其内部指针的参考,因为允许外部来源修改其Inards会破坏其安全的内存管理。

您想做的是这个

LDAP *ld;
ldap_initialize(&ld, "host_name");
if (ld)
    std::shared_ptr<LDAP> ldap(ld, [](LDAP * ld){ ldap_unbind(ld); });
else
   // This is up to you

这是有效的原因,并且安全的原因是ldap_initialize将仅在成功时为ld提供有效的值。您没有在其外部创建LDAP,在ldap_initialize的返回和shared_ptr的创建之间没有任何抛出,因此您无法获得内存泄漏。当然,您所希望的是更多的详细信息,但是您可以随时在返回shared_ptr<LDAP>的函数中初始化来减轻它。