Re: [讨论] Rust与C++

楼主: d8888 (Don)   2023-06-30 14:21:51
搬运下网络文章,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,还许久没碰,又是个业余玩票,说得不好请
指正了。
作者: shyin7089 (shyin7089)   2023-06-30 15:07:00
3. 其实在 Rust 也可能发生:https://julesjacobs.com/pdf/locks.pdf第一段 struct X 的程式码就有展示
作者: wei115 (ㄎㄎ)   2023-06-30 15:09:00
我也做过传stack的事情XD
作者: jheli (我是企鹅)   2023-06-30 15:23:00
推,每次看到程式无预警crash,第一个怀疑就是memory bug
作者: Dracarys (MayShowGunMore)   2023-06-30 16:33:00
4从C++17开始就不会发生了https://wg21.link/P0400R0
作者: tomsawyer (安安)   2023-07-01 05:16:00
1,2那种是要shared_ptr<int[]>才对吧?
作者: Lipraxde (Lipraxde)   2023-07-01 10:13:00
make_shared...为什么不用呢...?
作者: Dracarys (MayShowGunMore)   2023-07-01 15:15:00
为何要加array abstract declarator?

Links booklink

Contact Us: admin [ a t ] ucptt.com