2011-06-11 40 views
1

我有一个简单的类C++ STL地图:刀片存储空指针

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存储空指针。我无法解决这个问题,并尝试了许多变体,包括const和引用来取得利用。

+3

你将不得不发布'put_child'的代码。 – Puppy 2011-06-11 18:12:53

+0

刚刚在 – jmgun87 2011-06-11 18:16:34

+1

之上加注请注意,如果没有将比较对象传递给您的'map'(请参阅http://www.sgi.com/tech/stl/Map.html上的示例),您的'const char *'键将会出现比较指针,而不是字符串。 – 2011-06-11 18:18:18

回答

5

child_symbols[child->name.c_str()]将始终创建并返回一个新的地图条目(NULL值),然后child_symbols.insert(...)不会执行任何操作(因此地图中的值保持为NULL)。检查开关是否已经在地图上正确的方法是使用find

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

完美。已修复它。谢谢! – jmgun87 2011-06-11 18:27:29

+0

@ jmgun87如果它适合您,请不要忘记接受答案! – 2011-06-11 18:28:54

+1

这是不正确的。它*将*总是创建一个NULL条目 - 在if语句中将被转换为'false'并且* not * return。 – Puppy 2011-06-11 19:05:25

4

您正在比较指针的价值。你需要比较他们指向。例如:

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

这就是为什么使用C-串的绝对不是认为是一个C++适当编程 - std::string比较由值。

+0

我同意,因此我对这个问题发表了评论,但我不明白它会如何阻止他的例子工作。 – 2011-06-11 18:20:53

1

child_symbols[child->name.c_str()]不会做你认为它做的事情:这会插入一个默认对象,在你的情况下每次都插入一个symbol_entry指针。我可能是错的,但我认为

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

将始终评估为true因为std::map将插入你的一个项目。

0

如果插图已经存在于地图中,插入将不会执行任何操作。您的支票child_symbols[child->name.c_str()]将在默认状态下创建该元素,所以会发生这种情况。

你可以使用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*来修复

1

此:

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

是不是OK:您存储c_str的结果(),这是不一个持久的价值。它给你一个指向一个C字符串的指针,该字符串在你调用它后立即生效,但是它对于以后的存储和读取无效。你应该让你的地图使用std :: string作为它的关键类型。