【问题标题】:C++ smart pointer needed for string object on heap?堆上的字符串对象需要 C++ 智能指针吗?
【发布时间】:2016-10-17 12:47:35
【问题描述】:

我试图证明我的问题。我不能提供一个完整的例子,但我想我的问题会很清楚。

我有这个构造函数:

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

如你所见,我使用了一个转换hostaddr的静态函数:

#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::Client::ip_and_port 声明为:

const string ip_and_port;

据我了解,我在堆上创建了一个字符串,并将取消引用的内容作为对 const 字符串的引用返回。此结果在初始化程序中用于初始化 const 字符串成员 ip_and_port。

这会产生内存泄漏吗?如果我调用“delete some_client_instance”并调用析构函数 mlt::Client::~Client() 会发生什么?

我是否必须在 mlt::Client::prepareIPandPort 中使用智能指针 (std::shared_ptr)?如果是这样,这段代码会是什么样子?

提前非常感谢

【问题讨论】:

  • 你是如何声明ip_and_port的?回答这个问题很重要。
  • 我很困惑。如何使用标识符 hostname 声明 ip_and_port
  • 为什么是指针?你可以有返回字符串,它会完成这项工作。更像是: string mlt::Client::prepareIPandPort(struct sockaddr *hostaddr) { ....
  • 我以为字符串只会在本地存在,离开堆栈后,变量会被杀死(移除堆栈)
  • 好的,所以删除指针,直接使用 std::string 代替。会更好。

标签: c++11 memory-leaks heap-memory shared-ptr


【解决方案1】:

是的,这会导致内存泄漏。您需要在函数结束时调用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)))
{ /* ... */ }

【讨论】:

  • 我现在收到编译器警告:----------------- 移动临时对象可防止复制省略 [-Wpessimizing-move] ip_and_port(move(mlt: :Client::prepareIPandPort(hostaddr)))
猜你喜欢
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
  • 2012-09-10
  • 2014-05-20
  • 1970-01-01
相关资源
最近更新 更多