为什么在try块中初始化文件指针会导致管道破裂
Why does initializing a file pointer inside a try block cause a broken pipe?
我有一个bash脚本,我正在从我的程序中读取结果。Ptr
是一个简单的popen()
包装器。
bool getResult(const char* path){
Ptr f(path);
char buf[1024];
while (fgets(buf, sizeof(buf), f) == 0) {
if(errno == EINTR)
continue;
log.error("Error (%d) : %s",errno,path);
return false;
}
...
return true;
}
这工作得很好,但Ptr f(path)
不是异常安全,所以我用:
Ptr f; // empty constructor, does nothing
char buf[1024];
try{
Ptr f(path);
}catch(Exception& e){
vlog.error("Could not open file at %s",path);
return false;
}
当运行(并且文件存在)时,我得到以下错误:
/etc/my_script: line 165: echo: write error: Broken pipe
脚本的那一行就是:
echo $result
怎么回事?
当你在try块中调用Ptr f(path)时,你创建了一个名为f的全新变量,当你退出try块时,它将被销毁。
那么任何在try块之外使用f的代码都将使用您在开始时创建的未初始化的f。
你有两个选项,我可以看到:
添加一个Open方法或类似于Ptr的方法,并从try块中调用它,或者可能将所有文件读/写代码包装在try块中,这样您就可以避免返回false的需要,因为当抛出异常时所有代码都将被跳过。
选项1:
Ptr f;
try
{
f.Open( file );
}
catch
....
选项2:
try
{
Ptr f( file );
f.read();
}
catch
.....
这可能是一个作用域问题,替换为:
bool getResult(const char* path)
{
try
{
Ptr f(path);
char buf[1024];
while (fgets(buf, sizeof(buf), f) == 0)
{
if(errno == EINTR)
continue;
log.error("Error (%d) : %s",errno,path);
return false;
}
...
}
catch(Exception& e)
{
vlog.error("Could not open file at %s",path);
return false;
}
return true;
}
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 如何检查文件指针/描述符/句柄是否关联到同一个文件/管道/终端
- 无法使用 istream 和 ostream 指针跨 Linux 管道写入
- 以何种形式,可以通过管道将空指针发送到不同进程地址空间中的另一个进程
- 为什么在try块中初始化文件指针会导致管道破裂