stringのc_str()の指す先が破壊される

stringで作った文字列をc_str()でconst char*に受けたとき、後でそれを参照しようとすると値が破壊されている。

ソースはこんな感じ。

#include <iostream>
#include <mpi.h>
#include <string>
#include <sstream>
#include <fstream>
#include <iomanip>
using namespace std;

int
main(int argc,char **argv){
  int myid;
  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD,&myid);
  stringstream ss;
  ss << "test" << setw(3) << setfill('0') << myid << ".dat";
  fstream fs;
  const char *filename = ss.str().c_str();
  cout << "before:" << filename << endl;
  fs.open(filename);
  fs.close();
  cout << "after:" << filename << endl;
  MPI_Finalize();
}

実行結果はこんな感じ。

$./test
before:test000.dat
after:test000.dat

$ mpiexec -np 1 ./test
before:test000.dat
after:

 つまり、mpiexecで実行したときに限り、ファイルを開いた後const char *filenameの指す先が破壊されている。「-np 1」を指定しているので、複数プロセスの干渉ではない。もちろんssの保持する値は生きているので、fs.close()の後に ss.str().c_str()とすると正しい値が帰ってくる。

MPIのせいかとも思ったが、昔「c_str()の返すポインタの指す値は直後しか保証されない」ということを聞いたような気がする。とりあえず覚書としてメモ。