私は次のクラスを持っています:
class StdinIo : public FileIo{
public:
StdinIo();
~StdinIo();
static StdinIo* createObj(const std::string&);
static bool checkPath(const std::string&);
private:
std::string tempPath;
std::string newPath();
};
実装 1:
StdinIo::StdinIo()
:FileIo(newPath())
{
}
std::string StdinIo::newPath(){
printf("%s Using FileIo\n", __PRETTY_FUNCTION__);
std::stringstream tempPathStream;
tempPathStream << tmpnam(NULL) << getpid();
tempPathStream.flush();
const char* szTempPath = tempPathStream.str().c_str();
FILE *fp=fopen(szTempPath,"wb");
size_t rv=1;
char buffer[1024*8];
if(fp){
while(rv){
rv=fread(buffer,1,sizeof(buffer),stdin);
fwrite(buffer,1,rv,fp);
}
fclose(fp);
}
return tempPathStream.str();
}
実装 2:
StdinIo::StdinIo()
:FileIo(newPath())
{
}
std::string StdinIo::newPath(){
printf("%s Using FileIo\n", __PRETTY_FUNCTION__);
std::stringstream tempPathStream;
tempPathStream << tmpnam(NULL) << getpid();
tempPathStream.flush();
tempPath = tempPathStream.str();
const char* szTempPath = tempPath.c_str();
FILE *fp=fopen(szTempPath,"wb");
size_t rv=1;
char buffer[1024*8];
if(fp){
while(rv){
rv=fread(buffer,1,sizeof(buffer),stdin);
fwrite(buffer,1,rv,fp);
}
fclose(fp);
}
return tempPath;
}
スタックに関する私の知識によると、実装 1 は segFault を与えるべきであり、実装 2 はすべきではありません。しかし、逆のことが起こっています。理由がわかりません。
後でデストラクタでファイルを削除できるように、クラス メンバとして tempPath 文字列が必要です。
StdinIo::~StdinIo(){
if( unlink(tempPath.c_str()) != 0 )
perror( "Error deleting file" );
}
あちこちの行をコメントアウトした後、次の行でseg-faultが発生することがわかりました。
tempPath = tempPathStream.str();
gdb 言います:
Program received signal SIGSEGV, Segmentation fault.
__exchange_and_add_dispatch (__mem=0xfffffffffffffff8, __val=<optimized out>)
at /usr/src/debug/gcc-4.7.2-20120921/obj-x86_64-redhat-linux/x86_64-redhat- linux/libstdc++-v3/include/ext/atomicity.h:83
83 return __exchange_and_add_single(__mem, __val);