C++ C++;STL映射:insert正在存储空指针
我有一节简单的课C++ C++;STL映射:insert正在存储空指针,c++,stl,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 cha
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* 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;
symbol_entry*tsym=新符号_entry(“test”、“$”、0,0,0);
symbol_entry*tcsym=新的symbol_条目(“test_child”,“$”,0,0,0);
tsym->put_child(tcsym);
std::coutfirst您正在按值比较指针。你需要比较他们所指的东西。例如:
std::string s1 = "Hello World!";
std::string s2 = s1;
s1.c_str() != s2.c_str()
<>这就是为什么C字符串在C++程序中不被认为是合适的-<代码> STD::String 按值比较。 < P>你正在按值比较指针。你需要比较他们所指的东西。例如:
std::string s1 = "Hello World!";
std::string s2 = s1;
s1.c_str() != s2.c_str()
<>这就是为什么C字符串在C++程序中不被认为是适当的-<代码> STD::String 按值比较。<> >代码>子符号[CHIV[>No.CyString()] < /C>不按你的想法做:它插入一个默认对象,在你的情况下,每次都是一个<代码>符号符号指针。我可能错了,但我认为
if(child_symbols[child->name.c_str()])
将始终计算为true
,因为std::map
将为您插入一个条目。child\u符号[child->name.c\u str()]
不会做您认为它会做的事情:每次都会插入一个默认对象,在您的情况下,它是一个symbol\u条目
指针。我可能错了,但我认为
if(child_symbols[child->name.c_str()])
将始终计算为true
,因为std::map
将为您插入一个条目。如果映射中已存在元素,则插入将不会起任何作用。您的检查child\u symbols[child->name.c\u 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*
来修复如果映射中已经存在元素,则插入将不起任何作用。您的检查child\u symbols[child->name.c\u 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*
来修复子符号[child->name.c_str()]
将始终创建并返回一个新的映射条目(一个空条目),然后子符号。插入(…)
不做任何事情(因此映射中的值保持为空)。检查该键是否已在地图中的正确方法是使用find
:
if (child_symbols.find(...) != child_symbols.end()) // already exists
child\u symbols[child->name.c\u str()]
将始终创建并返回一个新的映射条目(空条目),然后child\u symbols.insert(…)
不执行任何操作(因此映射中的值保持为空)。检查该键是否已在地图中的正确方法是使用find
:
if (child_symbols.find(...) != child_symbols.end()) // already exists
这:
不正常:您正在存储c_str()的结果,该结果不是持久值。它为您提供一个指向C字符串的指针,该指针在您调用它之后立即有效,但对于以后的存储和读取无效。您应该使映射使用std::string作为其键类型。此:
不正常:您正在存储c_str()的结果,该结果不是持久值。它为您提供一个指向C字符串的指针,该指针在您调用它之后立即有效,但对于以后的存储和读取无效。您应该使映射使用std::string作为其键类型。您必须发布put\u child
的代码。请注意,如果没有传递给map
的比较对象,则const char*
键将作为指针进行比较,不作为字符串。您必须发布put\u child
的代码。请注意,如果没有传递给映射的比较对象
(参见中的示例),您的const char*
键将作为指针进行比较,而不是作为字符串。我同意,因此我对这个问题的评论,但我不认为这会阻止他的榜样发挥作用。我同意,因此我对这个问题的评论,但我不认为这会阻止他的榜样发挥作用。@jmgun87如果对你有效,别忘了接受答案!这不是真的。它将始终创建一个空条目-它将在if语句中转换为false
,而不会返回。@DeadMG:Oh,对了。但变化不大,因为map::insert
将不起作用(函数达到return true
,但值保持为空)。@jmgun87如果对您有效,请不要忘记接受答案!这不是真的。它将始终创建一个空条目-它将在if语句中转换为false
,而不会返回。@DeadMG:Oh,对了。但变化不大,因为map::insert
将是no op(函数达到return true
,但值保持为NULL)。