- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这段代码
#include <iostream>
#include <memory>
template <typename T>
class ScopeGuard final {
public:
explicit ScopeGuard(T callback) : callback_(std::move(callback)) {}
ScopeGuard(const ScopeGuard&) = delete;
ScopeGuard(ScopeGuard&&) = delete;
ScopeGuard& operator=(const ScopeGuard&) = delete;
ScopeGuard& operator=(ScopeGuard&&) = delete;
~ScopeGuard() noexcept(false) { callback_(); }
private:
T callback_;
};
static int a_instances = 0;
struct A {
A() {
++a_instances;
std::cout << "ctor" << std::endl;
}
A(A&&) = delete;
A(const A&) = delete;
~A() {
--a_instances;
std::cout << "dtor" << std::endl;
}
};
struct Res {
std::shared_ptr<A> shared;
explicit Res(std::shared_ptr<A> shared) : shared(shared) {
std::cout << "res ctor" << std::endl;
}
Res(Res&& o) : shared(std::move(o.shared)) {
std::cout << "res mv" << std::endl;
}
Res(const Res& o) : shared(o.shared) { std::cout << "res cp" << std::endl; }
~Res() { std::cout << "res dtor" << std::endl; }
};
Res LeakImpl() {
ScopeGuard on_exit{[] { throw std::runtime_error("error"); }};
Res res{std::make_shared<A>()};
return res;
}
void Leak() {
try {
auto res = LeakImpl();
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
}
int main() {
Leak();
if (a_instances) {
std::cout << "leak, instances count: " << a_instances << std::endl;
}
return 0;
}
输出这个(GCC 9.1、GCC 11.1 和 Clang 9.0.1)
ctor
res ctor
error
leak, instances count: 1
这意味着
A::~A()
,也不是
Res::~Res()
被调用,导致这种情况下内存泄漏。
LeakImpl()
Res::~Res()
之前没有被调用过
ScopeGuard::~ScopeGuard
因为复制省略,但为什么在从
ScopeGuard::~ScopeGuard
抛出异常时不调用它左
try
堵塞?
LeakImpl()
像这样:
Res LeakImpl() {
ScopeGuard on_exit{[] { throw std::runtime_error("error"); }};
return Res{std::make_shared<A>()};
}
然后 GCC 11.1 生成二进制输出:
ctor
res ctor
res dtor
dtor
error
无泄漏
最佳答案
似乎是一个错误,已经为 gcc 报告和修复:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66139
我想,std::shared_ptr<>
在异常抛出期间部分创建
作为一种解决方法,您可以防止复制省略:
Res LeakImpl() {
ScopeGuard on_exit{[] { throw std::runtime_error("error"); }};
Res res{std::make_shared<A>()};
return std::move(res);
}
或创建
ScopeGuard
之前
Res
(在这种情况下,销毁顺序很重要):
Res LeakImpl() {
Res res{std::make_shared<A>()};
ScopeGuard on_exit{[] { throw std::runtime_error("error"); }};
return res;
}
关于c++ - 抛出析构函数导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68196695/
我开始考虑在我 future 的项目或重构中实现控制反转容器,我想知道在正确设计依赖项时哪些原则(除了 GoF 模式)可能需要牢记在心。假设我需要构建一个简单的控制台应用程序,如果它可以访问互联网,它
假设我有一个 RxC contingency table 。这意味着有 R 行和 C 列。我想要一个维度为 RC × (R + C − 2) 的矩阵 X,其中包含行的 R − 1 “主效应”以及列的
我正在尝试使用 DKMS 为正在运行的内核 (4.4) 构 build 备树覆盖。我天真的 Makefile 如下: PWD := $(shell pwd) dtbo-y += my-awsome-o
我有一个 sencha touch 项目。我是用 phonegap 2.9 构建的,并且可以正常工作 device.uuid 返回到设备 ID。当我尝试使用 3.1 device.uuid 构建时抛出
我在安装了 Xcode 4.5.1 的 Mt Lion 上运行。 默认情况下,当我构建并部署到 iOS 5.1 设备时,显示会在我旋转设备时旋转,但当我部署到 iOS 6 模拟器或运行 iOS 的 i
我正在尝试使用 Google Analytics Reporting API v4 构建多折线图。 一张图表,其中我按每天的 session 计数为每个设备(台式机/平板电脑/移动设备)设置了一条线。
我一生都无法使用 xcode 组织者“自动设备配置”中的“团队配置配置文件”在 xcode 4.0.1 中将我的应用程序构建到我的 iPad 上。 该应用程序完美地构建到模拟器,但当我构建到 iPad
我是一名优秀的程序员,十分优秀!