You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次std::move同一std::unique_ptr未崩溃,代码是否合法?

Great question! Let's break this down step by step to understand what's happening here, and whether your code is actually valid C++.

First, the key rule about moved-from std::unique_ptr

The C++ standard clearly states that after a std::unique_ptr is moved from, it's left in a valid but unspecified state. To translate that into plain terms:

  • It's still a legitimate, safe-to-manipulate object (you can destroy it, assign a new value to it, or even move from it again).
  • You cannot make any assumptions about its internal value—it might be null, it might still hold the original pointer, or it could be something else entirely. The standard doesn't lock in a specific state here.

What happens in your first fun(std::move(p)) call?

Let's walk through this line by line:

  1. When you call fun(std::move(p)), the ownership of the pointer stored in your local p is transferred to the function's parameter p (the one inside fun).
  2. Your fun function does whatever it needs to with the pointer, then returns it.
  3. Since you don't capture the return value, the returned std::unique_ptr is immediately destroyed. This means it releases the memory holding your X object (the one created with std::make_unique).
  4. The original p (in someFunction) is now stuck in that valid-but-unspecified state we talked about.

The act of calling std::move on the moved-from p is technically allowed—because the object is still valid, and moving from it is a permitted operation. But what happens next is where things get risky:

  • If your compiler/standard library implementation set p to null after the first move (most modern ones do this), then fun receives a null pointer. If fun doesn't dereference the pointer (e.g., it just returns it without accessing the X object), nothing bad happens.
  • If your implementation didn't set p to null (some older or non-conforming implementations might skip this), then p still holds the address of the already-deleted X object. This makes the pointer passed to fun a dangling pointer. If fun doesn't dereference it, you might get lucky and avoid a crash—but this is still undefined behavior (the C++ standard gives no guarantees about what happens here).

Why does your code run without crashing?

Your fun function probably doesn't perform any operations that dereference the pointer. Whether it gets a null pointer or a dangling one, simply passing it around and returning it won't trigger a crash. But this is pure luck—undefined behavior means the code could crash tomorrow, produce garbage results, or work fine depending on the compiler, optimization level, or even random chance.

The correct approach

If you intend to reuse p after calling fun, you need to capture the return value and reassign it to p:

p = fun(std::move(p));

This way, p regains ownership of the pointer (or whatever fun returns), and you're no longer relying on the unspecified state of a moved-from object. Alternatively, if you don't need p after the first call, you should avoid using it entirely to prevent accidental misuse.

内容的提问来源于stack exchange,提问作者softineer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:38:06