2

背景

我正在为网络协议编写驱动程序并有一个函数write(std::shared_ptr<package> package),其中packagestd::array<buffer_ptr,2>(0=>header,1=>body)。为方便起见,我想编写一个函数write(buffer_ptr body),该函数会自动生成标题并调用write. 为此,我想要我们std::make_shared,但是我在std::arraymake_shared通话中初始化时遇到了问题。

代码

typedef std::shared_ptr<std::vector<uint8_t>> buffer_ptr;
typedef std::array<buffer_ptr, 2> package_t;
typedef std::shared_ptr<package_t> package_ptr;

void connection::write(package_ptr package) {
    ... //do stuff
}

void connection::write(buffer_ptr body) {
    buffer_ptr header = buildHeader(body);
    write(std::make_shared<package_t>(???)) //here I want to initialize the array with {header,body}
}

我尝试了什么???

(这些导致编译器错误)

{header, body}
{{header, body}}
std::initializer_list<buffer_ptr>{header, body}

问题:

  1. 有没有解决方案来完成这项工作,还是我必须写一些类似的东西:

    package_ptr package=new package{header, body}; 写(包);

    1.b)我是否会因为不得不求助而失去效率package_ptr(new package)?(我记得在一个块中为指针和实例共享分配内存,以节省内存请求)

  2. Cppreference上读取:

    此外,如果 g 抛出异常, f(shared_ptr(new int(42)), g()) 可能会导致内存泄漏。如果使用 make_shared 则不存在此问题。

    为什么内存会泄漏(可以在被调用之前int(42)构造,在gg调用之前shared_ptr被调用)?1. 中的替代代码是否会遭受这种潜在的泄漏?

4

1 回答 1

1

第一的:

array没有显式声明构造函数。特别是,它没有采用初始化列表的构造函数。

我认为一种干净的方法是避免new代码中的显式并将其留给标准函数:

package_t p = {header, body};
write(std::make_shared<package_t>(p));

new如果既没有也没有,代码看起来会更好std::shared_ptr

package_t p = {header, body};
write(p);

其次,在Cppreference.com上显示:

此外,如果 g 抛出异常, f(shared_ptr(new int(42)), g()) 可能会导致内存泄漏。如果使用 make_shared 则不存在此问题。

该标准没有指定计算函数参数的顺序,只要它们产生相同的结果,就可以按任何顺序计算表达式。

f(shared_ptr(new int(42)), g())

new int(42)必须先于shared_ptr()但不是g(),如果g抛出,这可能会导致泄漏。

f(make_shared<int>(42), g())

分配发生在里面make_shared。如果g之前调用过make_shared并且如果它抛出,则永远不会分配内存。

如果make_shared在之前调用g并且如果g抛出,则该shared_ptr对象将已经创建,并且由于 RAII,它的销毁得到保证

于 2014-04-01T20:01:33.940 回答