2014-05-02 100 views
0

我有以下代碼。它編譯好,但它表明我的字符串是「E#^$ $ @ $$$$$$$」。 任何想法爲什麼?Ifstream trouble

ifstream InFile(Filename); 
if (!InFile) 
    return false; 
std::string Name; 
Song *pSong; 

for (int a = 0; a < Playlist.size(); a++) 
{ 
    delete Playlist[a]; 
} 
Playlist.clear(); 

while (true) 
{ 
    if (!InFile) 
     break; 

    pSong = new Song(); 

    std::getline(InFile, Name, '\n'); 
    pSong->File = const_cast<char*>(Name.c_str()); 
    std::getline(InFile, Name, '\n'); 
    pSong->Volume = atof(Name.c_str()); 

    Playlist.push_back(pSong); 
} 

播放列表:std::vector<Song*>Playlist;

+0

這是不安全的:'pSong-> File = const_cast (Name.c_str());'你現在有一個非const訪問std :: string內部。爲什麼不把'pSong.File'作爲'std :: string'並複製一份?究竟哪個字符串是「那個字符串」,哪個是錯誤的? – tillaert

+0

什麼是'Song :: File',它爲什麼不是'std :: string'?那麼它應該是'pSong-> File = Name;'(除了事實上你可能不需要用'new'分配'Song' ...) – crashmstr

+0

指針的副本不是內容的副本lookup dlingling pointer/reference) –

回答

3

這是有問題的線路。

pSong->File = const_cast<char*>(Name.c_str()); 

您正在存儲一個指向內存的指針,該內存在從文件中讀取下一行文本後將無效。

將其更改爲:

pSong->File = strdup(Name.c_str()); 

如果您的平臺沒有strdup,這裏有一個簡單的實現。

char* strdup(char const* s) 
{ 
    char* ret = malloc(strlen(s)+1); 
    strcpy(ret, s); 
    return ret; 
} 

注意 既然你在使用strdup分配內存,你必須確保你釋放它。

您可以選擇使用new來分配內存,因爲您使用的是C++。如果您使用new來分配內存,則必須使用delete來取消分配內存。如果您使用malloc分配內存(如此答案中所示),則必須使用free來取消分配內存。

+0

對不起 - strdup是邪惡的 –

+0

最好不要在C++中使用字符串'char *',它是C構造。使用'std :: string'。 – tillaert

+0

好吧,這是C++:不要使用'malloc',更好的解決方案是將類改爲使用'std :: string'而不是C字符串。 – crashmstr