Re: [討論] Rust與C++

看板C_and_CPP (C/C++)作者 (Don)時間1年前 (2023/06/30 14:21), 編輯推噓6(604)
留言10則, 6人參與, 1年前最新討論串3/3 (看更多)
搬運下網路文章,C++ 對 C 的記憶體管理「改善」並不完美 無法完全阻止開發者錯誤使用 引自:https://www.zhihu.com/question/400093693/answer/1270543164 1. std::shared_ptr 錯誤使用,記憶體被提前 free void process(std::shared_ptr<int> svp) {} int main(int argc, char** argv) { int* vp = new int(10); process(std::shared_ptr<int>(vp)); std::cout << *vp << std::endl; // pointer "vp" has already been released. return 0; } 2. 拿 std::shared_ptr 指 stack 變數造成 dangling pointer auto process() { int v = 10; int* vp = &v; return std::shared_ptr<int>(vp); } int main(int argc, char** argv) { std::cout << *process() << std::endl; // dangling pointer. return 0; } 3. 錯誤使用 shared_ptr 造成循環引用 struct C { ~C() { std::cerr << "destructor\n"; } std::shared_ptr<C> sp; }; int main(int argc, char **argv) { auto p = std::make_shared<C>(), q = std::make_shared<C>(); p->sp = q; q->sp = p; return 0; } 4. Potential memory leak 例子 bool complicatedCompute() { /* ... */ return true; } // potential memory leak; auto process(std::shared_ptr<int>, bool) {} int main(int argc, char** argv) { process(std::shared_ptr<int>(new int(10)), complicatedCompute()); return 0; } 由於 function call parameter 求值順序具有不確定性,理論上先 new -> 執行 complicatedCompute() -> 建立 shared_ptr 是合法的。 在這執行順序下,若 complicatedCompute 拋出異常,可能導致 new int(10) 不被 shared_ptr 管理,造成 memory leak。 當然這些例子是錯誤使用,會有人說問題出在寫程式的人,可以靠訓練和管理解決。但這 些例子 C++ compile 能過也是事實。 Rust 的嚴格記憶體管理則是讓可能有問題的程式連 compile 過的機會都沒有。淺見以為 在大型專案,程式碼多開發者混雜容易樹大有枯枝的情況下,Rust 把很多 runtime 可能 發生問題的地方,全部在 compile 攔下還是很有價值的。 以小弟自己玩 Rust 的經驗,還真的犯過在 multithreading 的情況下把 stack 上的東西 傳到另外一個 thread 的蠢事,然後被 rust 攔了下來。這種 bug 事後來看都很容易,但 寫到頭昏腦脹又沒經驗的時候就是有可能發生,如果被 compiler 放過去,runtime 有可 能出現一個時不時發生的 segmentation fault,debug 成本是 compile time 就能抓出來 情況下的數倍。 Limitation:小弟只粗淺涉獵 C++98/C++0x,還許久沒碰,又是個業餘玩票,說得不好請 指正了。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.127.72.143 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1688106114.A.B40.html

06/30 15:07, 1年前 , 1F
3. 其實在 Rust 也可能發生:
06/30 15:07, 1F

06/30 15:07, 1年前 , 2F

06/30 15:08, 1年前 , 3F
第一段 struct X 的程式碼就有展示
06/30 15:08, 3F

06/30 15:09, 1年前 , 4F
我也做過傳stack的事情XD
06/30 15:09, 4F

06/30 15:23, 1年前 , 5F
推,每次看到程式無預警crash,第一個懷疑就是memory bug
06/30 15:23, 5F

06/30 16:33, 1年前 , 6F
4從C++17開始就不會發生了
06/30 16:33, 6F

06/30 16:40, 1年前 , 7F

07/01 05:16, 1年前 , 8F
1,2那種是要shared_ptr<int[]>才對吧?
07/01 05:16, 8F

07/01 10:13, 1年前 , 9F
make_shared...為什麼不用呢...?
07/01 10:13, 9F

07/01 15:15, 1年前 , 10F
為何要加array abstract declarator?
07/01 15:15, 10F
文章代碼(AID): #1addI2j0 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1addI2j0 (C_and_CPP)