2016-06-16 5 views
0

私は私の問題を実証するためにtriy。私は完全な例を提供することはできませんが、私の質問ははっきりしていると思います。ヒープ上の文字列オブジェクトに必要なC++スマートポインタ?

#include <iostream> 
#include <libnet.h> 

const string& mlt::Client::prepareIPandPort(struct sockaddr *hostaddr) { 
    assert(hostaddr != nullptr); 

    string *ipport; 
    char clienthost[NI_MAXHOST]; 
    char clientport[NI_MAXSERV]; 
    int result = getnameinfo(hostaddr, sizeof(*hostaddr), 
          clienthost, sizeof(clienthost), 
          clientport, sizeof(clientport), 
          NI_NUMERICHOST | NI_NUMERICSERV); 

    if (result != 0) { 
     cerr << "Error: " << gai_strerror(result) << endl; 
     ipport = new string {"unknown"}; 
    } 
    else { 
     switch (hostaddr->sa_family) { 
      case AF_INET: 
       ipport = new string {string(clienthost) + ":" 
            + string(clientport)}; 
       break; 
      case AF_INET6: 
       ipport = new string {"[" + string(clienthost) + "]:" 
            + string(clientport)}; 
       break; 
      default: 
       ipport = new string {"unknown"}; 
     } 
    } 

    return *ipport; 
} 

MLT ::クライアント:: ip_and_portは次のように宣言されています:あなたが見ることができるように

mlt::Client::Client(const string& hostname, struct sockaddr *hostaddr) 
     : content(nullptr), 
      hostname(hostname), 
      ip_and_port(mlt::Client::prepareIPandPort(hostaddr)) 
{ /* ... */ } 

が、私はHOSTADDR変換静的関数を使用します。

私はこのコンストラクタを持っている

const string ip_and_port; 

私の理解では、ヒープ上に文字列を作成し、逆参照されたコンテンツを参照として返しますo const文字列。この結果は、イニシャライザでconst文字列メンバip_and_portを初期化するために使用されます。

これはメモリリークを引き起こしますか? "some_client_instanceを削除"し、デストラクタmlt :: Client ::〜Client()を呼び出すとどうなりますか?

mlt :: Client :: prepareIPandPortでスマートポインタ(std :: shared_ptr)を使用する必要がありますか?もしそうなら、このコードはどのように見えますか?

ありがとうございました

+0

どのようにip_and_portを宣言しましたか?これは答えることが重要です。 – galinette

+0

私は混乱しています。 'ip_and_port'は識別子' hostname'でどのように宣言できますか? – PcAF

+1

なぜポインタですか?あなたは文字列を返すことができた、それは仕事をしただろう。 何かもっと似ています: string mlt :: Client :: prepareIPandPort(struct sockaddr * hostaddr){ .... – Greg

答えて

0

はい、これによりメモリリークが発生します。あなたの機能の最後にdelete some_client_instanceに電話する必要があります。

理想的には、あなたがすべきである:mlt::Client::prepareIPandPort

    • 戻り、プレーン文字列(ない参照)が

    以下のようなip_and_port

  • 初期ip_and_portためのプレーンな文字列をこのように使用します文字列は一度だけ作成され、コピーされることはありません。

    mlt::Client::Client(const string & hostname, struct sockaddr *hostaddr) 
         : content(nullptr), 
          hostname(hostname), 
          ip_and_port(std::move(mlt::Client::prepareIPandPort(hostaddr))) 
    { /* ... */ } 
    
  • +0

    今すぐコンパイラの警告が表示されます。 ----------------- 一時オブジェクトを移動するとコピーの破損を防ぐ[-Wpessimizing-move] ip_and_port(move(mlt :: Client :: prepareIPandPort(hostaddr))) –

    関連する問題