C++STL映射:insert正在存储空指针
C++ STL map: insert is storing null pointers
我有一个简单的类
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()->第二个是存储一个空指针。我无法解决这个问题,并尝试了许多变体,包括const和对的引用。
child_symbols[child->name.c_str()]
将始终创建并返回一个新的映射条目(一个NULL条目),然后child_symbols.insert(...)
不执行任何操作(因此映射中的值保持为NULL)。检查钥匙是否已经在地图中的正确方法是使用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()]
不会做您认为它会做的事情:它每次都会插入一个默认对象,在您的情况下是一个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字符串的指针,该字符串在您调用后立即有效,但对于以后的存储和读取无效。您应该使用std::string作为映射的键类型。
如果映射中已经存在元素,则插入将不起任何作用。您的检查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*
来修复
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 运行时错误:引用绑定到类型为"int"的空指针
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 为什么我在空指针错误(链表)中获取成员访问权限
- 从向量到空指针的 memcpy(反之亦然)不起作用
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 成员访问是否在空指针上定义C++?
- 尝试将对象插入空指针数组时出现分段错误
- 为什么我们需要在 C++ 中检查空指针,而在 Java 中不需要?
- 存储函数指针的正确语法
- 是否允许向空指针添加零?
- 为什么 C 样式字符串的工作空指针检查不?
- 在函数内初始化无符号字符指针将返回空指针
- 如何捕获函数参数并存储函数指针以供以后在 C++11 中执行?
- 为什么多维数组中的空字符串文本衰减为空指针?
- C++ 取消引用指向矢量的空指针时的分段错误
- 错误 C6011:取消引用空指针"NAME"。C++
- 销毁存储为空指针的类对象
- 复制存储在空指针的整型数组到整型数组
- C++STL映射:insert正在存储空指针