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()の返すポインタの指す値は直後しか保証されない」ということを聞いたような気がする。とりあえず覚書としてメモ。