我正在编写网络协议的驱动程序,并且函数为write(std::shared_ptr<package> package)
,其中package
为std::array<buffer_ptr,2>
(0 =&gt;标题,1 =&gt;正文)。为方便起见,我想编写一个函数write(buffer_ptr body)
,它会自动生成标题并调用write
的第一种形式。为此,我希望我们std::make_shared
,但是我在std::array
来电中初始化make_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}
是否有解决方案可以完成这项工作,或者我必须写下类似的内容:
package_ptr package = new package {header,body}; 写(包);
1.b)我是否因为不得不诉诸package_ptr(new package)
而失去效率? (我记得在一个块中为指针和实例共享内存,以节省内存请求)
在Cppreference上显示为:
此外,f(shared_ptr(new int(42)),g())可能导致内存泄漏 如果g抛出异常。如果make_shared是,则不存在此问题 使用
为什么会泄露内存(可以在调用int(42)
之前构建g
,并在调用g
之前调用shared_ptr
?而来自1的替代代码是否会遭受这种潜在的泄漏?
答案 0 :(得分: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上的内容为:
此外,f(shared_ptr(new int(42)),g()) 如果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
,则{{1}}对象已经创建,并且由于RAII而保证了它的销毁