簡體   English   中英

C++ STL map:插入存儲 Z37A6259CC0C1DAE299A7866489DFF0BD

[英]C++ STL map: insert is storing null pointers

我有一個簡單的 class

    class symbol_entry
{
private:
    static unsigned long uid;

public:
    std::string name;
    std::string filename;
    unsigned int line_number;
    unsigned int column_number;
    symbol_entry* parent_symbol;
    std::map<const char*,symbol_entry*> child_symbols;
    unsigned long type_flags;

public:
    symbol_entry();
    symbol_entry(const char* name,
                 const char* filename,
                 int line_number,
                 int column_number,
                 symbol_entry* parent_symbol,
                 unsigned long type_flags);
    ~symbol_entry();

    symbol_entry* get_child(const char* name);
    bool put_child(symbol_entry* child);
};

這里是 symbol_entry::put_child 的實現;

bool symbol_entry::put_child(symbol_entry* child)
{   
    if(child_symbols[child->name.c_str()])
        return false;
    child_symbols.insert(std::make_pair(child->name.c_str(),child));
    return true;
}

每當我進行這樣的測試時;

symbol_entry* tsym=new symbol_entry("test","$",0,0,0,0);
symbol_entry* tcsym=new symbol_entry("test_child","$",0,0,0,0);
tsym->put_child(tcsym);
std::cout<<tsym->child_symbols.begin()->first<<" => "<<tsym->child_symbols.begin()->second<<std::endl;

child_symbols.begin()->second 存儲一個 null 指針。 我無法解決這個問題,並嘗試了許多變體,包括 const 和引用。

child_symbols[child->name.c_str()]將始終創建並返回新的Z1D78DC8DC8ED51214E518B5114FE24490AEZ條目(A Z6C3E2226B4D4795518B341B01B01B01B01B01B01B01B014NET14BY11NEBR.NOTINB.NOTHING SENB.IND INB.INS)INS INS(INS) child_symbols.insert(...) INS)(INS)(INS)(INS)(IST) )。 檢查密鑰是否已經在 map 中的正確方法是使用find

if (child_symbols.find(...) != child_symbols.end()) // already exists

您正在按值比較指針。 您需要比較他們所指的內容 例子:

std::string s1 = "Hello World!";
std::string s2 = s1;
s1.c_str() != s2.c_str()

這就是為什么在 C++ 程序中使用 C 字符串絕對不合適的原因 - std::string按值進行比較。

child_symbols[child->name.c_str()]並沒有做你認為它做的事情:這會插入一個默認的 object,在你的例子中是一個symbol_entry指針,每次。 我可能是錯的,但我認為

if(child_symbols[child->name.c_str()])

將始終評估為true ,因為std::map將為您插入一個條目。

這個:

child_symbols.insert(std::make_pair(child->name.c_str(),child));

不行:您正在存儲 c_str() 的結果,這不是一個持久值。 它為您提供了一個指向 C 字符串的指針,該字符串在您調用它后立即有效,但對於以后的存儲和讀取無效。 你應該讓你的 map 使用 std::string 作為它的鍵類型。

如果 map 中已存在元素,則插入將不執行任何操作。 您的檢查child_symbols[child->name.c_str()]將在其默認 state 中創建元素,所以這就是發生的事情。

您可以使用find代替進行檢查,但insert已經內置:

bool symbol_entry::put_child(symbol_entry* child)
{
    return child_symbols.insert(std::make_pair(child->name,child)).second;
}

編輯:另外,DeadMG 所說的 - 使用std::string而不是const char*來解決這個問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM