2012-05-11 59 views
2

我寫一個編譯器,並使用雙端隊列來存儲一個類的方法,標籤和這裏的示例代碼:雙端隊列推回錯誤

#include <deque> 
#include <iostream> 
#include <string> 

using std::cout; 
using std::deque; 
using std::endl; 
using std::string; 

int main() 
{ 
    deque<const char *> names; 

    string prefix = "___"; 
    const char *classname = "Point"; 

    const char *methodname[] = {"Init", "PrintBoth", "PrintSelf", "equals"}; 

    for (int i = 0; i < 4; i++) 
    { 
     string label = prefix + classname + "." + methodname[i]; 
     names.push_back(label.c_str()); 
    } 

    for (int i = 0; i < 4; i++) 
    cout << names[i] << endl; 

    return 0; 
} 

但是,結果不是我所期待的:

___Point 
___Point.PrintSelf 
___Point.PrintSelf 
___Point.equals 

而且,我發現,如果我只逼退方法名

names.push_back(methodname[i]) 

我得到的所有的方法名秩序。

我在這裏做了什麼錯?

回答

8
for (int i = 0; i < 4; i++) 
{ 
    string label = prefix + classname + "." + methodname[i]; 
    names.push_back(label.c_str()); //what you're pushing? a temporary! 

} //<--- `label` is destroyed here and it's memory is freed. 

這裏label是得到在閉括號破壞和再次被創建的,在每次迭代中的一個變量。

這意味着,您推送到names是一個臨時值。這是造成這個問題的原因。

我會建議你使用這樣的:

std::deque<std::string> names; 

然後做到這一點:

names.push_back(label); //a copy is pushed to the deque! 
+1

quick typer !!!! –

+0

因此label.c_str()返回的指針指向標籤存儲空間內的某個位置? – manuzhang

+0

@manuzhang:是的。 'label.c_str()'返回的是一個由'label'管理的指針。所以當'label'被銷燬時,它管理的內存就被釋放了。 – Nawaz

0

這是因爲string label是暫時的,其chhar指針不是一旦退出有效範圍 - for循環,在這種情況下。

我建議改用deque<string>。這樣你可以自己推label,然後在deque裏面創建一個label的真實副本。