std::move转移std::shared_ptr持有的FILE指针后仍可写入的原因咨询
C++智能指针相关问题解答
1. std::move转移shared_ptr后,原始FILE指针仍可写入的原因及语法合规性
你通过std::move将file_guard的所有权转移给hal1后,file_guard会变为空的std::shared_ptr,但原始的FILE* file指针本身并未被修改——std::shared_ptr仅负责托管指针的生命周期,不会剥夺原始指针的访问权限。
这种写法语法上是合规的,但行为极度危险:std::shared_ptr会在最后一个持有它的对象销毁时调用fclose关闭文件。如果之后再用原始FILE*指针写入,就属于访问已关闭的文件句柄,这是未定义行为,只是当前编译环境未立刻触发崩溃而已。
2. 取消大括号注释后无法访问文件的原因
完全正确。当你添加大括号创建局部作用域后,hal1的生命周期被限制在该作用域内,作用域结束时hal1会被销毁。由于你用std::move将file_guard的所有权转移给了hal1,此时hal1是std::shared_ptr<FILE>的唯一持有者,销毁hal1时会触发std::shared_ptr的析构逻辑,调用fclose关闭文件。后续再用原始FILE*指针写入,自然会因文件已关闭而失败。
3. 编辑后的代码添加std::move是否导致未定义行为?
是的,添加std::move后会触发未定义行为,最终导致文件无内容,具体原因如下:
看你修改后的代码片段:
{ Hal hal1{std::move(file_guard)}; // 添加std::move hal1.write_status("I'm completely operational1\n", 8); }
- 执行
std::move(file_guard)后,file_guard会被置为空的std::shared_ptr; - 大括号结束时
hal1销毁,它是当前std::shared_ptr<FILE>的唯一持有者,会调用fclose关闭文件; - 后续用空的
file_guard构造hal2,hal2内的std::shared_ptr同样为空,调用write_status时file.get()返回空指针,fprintf传入空指针属于未定义行为,无法写入内容; - 最后一行的
fprintf(file, ...),file指针指向的文件已经被hal1析构时关闭,访问已关闭的文件句柄同样是未定义行为。
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

