2013-04-06 89 views
1

我有下面的類:Segfault將一個std :: string複製到另一個?

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應該給段錯誤與實現2不應該。但相反的情況正在發生。我無法弄清楚爲什麼。

我需要tempPath字符串作爲類成員,以便我可以稍後在析構函數中刪除該文件。

StdinIo::~StdinIo(){ 
     if(unlink(tempPath.c_str()) != 0) 
       perror("Error deleting file"); 
} 

在這裏和那裏註釋掉行後,我發現,在下面的行,賽格故障發生:

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); 
+0

@stardust_:'TEMPPATH = tempPathStream.str();' – 2013-04-06 15:21:00

回答

1

你的第二個實現電話newPath()並在對象完全初始化之前訪問tempPath(將它傳遞給基類構造函數)。這導致未定義的行爲。

如果你絕對需要文件名的本地副本而不對現有代碼進行重大更改,則可以使用實現#1進行類似的操作。

class StdIoSpecialData : public FileIo 
{ 
protected: 

    StdIoSpecialData(const std::string &fname) 
     : FileIo(fname), 
      tempPath(fname) 
    { 
    } 
    const std::string tempPath; 
}; 

class StdIo : public StdIoSpecialData 
{ 
public: 
    StdIo() 
     : StdIoSpecialData(newPath()) 
    { 
    } 
}; 
+0

即使我寫的語句:'TEMPPATH = tempPathStream.str();'實施1和返回tempPathStream.str();我得到一個seg-fault – 2013-04-06 15:15:52

+0

因爲你正在訪問'tempPath'並且它還沒有被初始化。您正在嘗試將字符串分配給不存在的對象。 – 2013-04-06 15:18:45

+0

我已經更新了這個問題。 @Captain Oblivious如何初始化它? – 2013-04-06 15:19:39

相關問題