簡體   English   中英

將shared_ptr作為指針傳遞給指針

[英]Pass shared_ptr as pointer to pointer

我有一個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");

但是上面的代碼不起作用。 有什么方法可以將shared_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>的函數中進行初始化來緩解這種情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM