網站首頁 編程語言 正文
Lambda介紹
“Lambda表達式是現代C++在C ++ 11和更高版本中的一個新的語法糖 ,在C++11、C++14、C++17和C++20中Lambda表達的內容還在不斷更新。 lambda表達式(也稱為lambda函數)是在調用或作為函數參數傳遞的位置處定義匿名函數對象的便捷方法。通常,lambda用于封裝傳遞給算法或異步方法的幾行代碼 。
c++的lambda 可以捕獲this指針,使lambda可以在自定義的function內使用類的成員函數,這是因為捕獲this后隱式的在成員變量前加了this
但是需要注意的是,這里捕獲this,不是以一種拷貝的方式,更像是一種引用(或者別名,描述可能不準確),當在外面這個類的生命周期結束時,lambda內部還在調用這個類的成員函數,那么就會出錯
我遇到的問題是 捕獲了類A的this,對A的一個shared_ptr進行操作。偶然會出現shared_ptr的內部基類spt_count_base的報錯。看了下這個shared_ptr 的use_count和weak_count都是0,
這就非常奇怪。shared_ptr計數是線程安全的,(但是實際指向對象和計數不是原子操作),并且訪問這個sptr也加了鎖,為什么會出現被釋放了的情況。
大概再說下情景
class A
{
shared_ptr<B> sptr;
sptr.func = [this](){ do something};
}
class B
{
shared_ptr<map> sptrMap;
func()
{
//概率崩潰
sptrMap.erase();
}
}
當A被析構后,B注冊的回調被另一個線程調用了func();這時可能會出現A開始析構,剛好析構到B,并且B的sptrMap已經析構時,出現崩潰。但這個順序不是確定的無法保證,所以也不一定必出現這種現象。
防止這種現象可以加個判斷,在sptrMAp不為空時不進行析構。或者用weak_ptr.在捕獲this前,用 weak_ptr p = std::shared_from_this;然后在lambda最開始用p.lock判斷A是否釋放
通過這個了解到了lambda捕獲的一個坑,及類析構的順序及析構時線程安全的保護
另附實際代碼
using namespace std;
struct Foo {
std::unique_ptr<int> p;
std::function<void()> f() {
p.reset(new int(1));
return [=] { cout << *p << endl; };
}
};
int main() {
auto foo = new Foo();
auto f = foo->f();
delete foo;
f();
}
運行結果為0而非1,而且這里輸出0是未定義行為,因為訪問的實際上是被回收的空間,只是因為編譯器的delete并沒有對回收的空間做額外的操作,所以p指向的仍然是原來那塊,只不過那塊已經被unique_ptr的析構函數自動清除了,只不過將清除的部分全部置為0而已。
原文鏈接:https://www.cnblogs.com/wangshaowei/p/14696424.html
相關推薦
- 2022-09-21 Django中外鍵使用總結_python
- 2023-02-06 C語言預處理器使用方法講解_C 語言
- 2022-04-10 Blazor數據綁定用法_基礎應用
- 2022-10-27 Python?標準庫?fileinput與文件迭代器_python
- 2022-10-15 使用Pycharm創建一個Django項目的超詳細圖文教程_python
- 2022-05-21 Python遞歸時間復雜度_python
- 2022-05-03 C#面向對象設計原則之單一職責原則_C#教程
- 2022-06-07 FreeRTOS實時操作系統移植操作示例指南_操作系統
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支