1

プログラムで結果を読み取っている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

何が起こっている?

4

2 に答える 2

3

tryブロックでPtrf(path)を呼び出すと、fというまったく新しい変数が作成されます。この変数は、tryブロックを終了すると破棄されます。

次に、f outsidde tryブロックを使用するコードは、最初に作成した初期化されていないFを使用します。

私が見ることができる2つのオプションがあります:

OpenメソッドまたはPtrに類似したものを追加し、tryブロック内から呼び出すか、すべてのファイルの読み取り/書き込みコードをtryブロックでラップします。これにより、すべてのコードが行われるため、falseを返す必要がなくなります。例外がスローされたときにスキップされました。

オプション1:

Ptr f;
try
{
    f.Open( file );
}
catch
....

オプション2:

try
{
    Ptr f( file );
    f.read();
}
catch
.....
于 2011-11-15T12:44:53.553 に答える
1

おそらくスコーピングの問題です。次のように置き換えてください。

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;
}
于 2011-11-15T12:44:58.840 に答える