【问题标题】:Weird floating point exception c++ (pointer assignment)奇怪的浮点异常c++(指针赋值)
【发布时间】:2020-07-27 05:50:18
【问题描述】:

我想创建一个树状结构,但基于 unordered_map 的主题。简而言之,我想创建一个主题树,我想到了这种方法:

typedef struct topic_tree {
    int id;
    unordered_map<string, struct topic_tree *> children;
} topic_tree;

这听起来是个好主意,因为对于每个“主题”,我都会有一个 ID(或任何我需要的),并且从每个节点都会有一个从下一个字符串到下一个 topic_tree 的映射,并且以此类推。

我尝试创建这棵树:first/second/third。这意味着首先它是第二个的父级,第二个是第三个的父级.. 可能还有其他类似first/forth/fifty 这意味着第一个现在有两个孩子,第二个和第四个......这就是解释。现在让我们解决问题:

例如我这样声明:

topic_tree *root = (topic_tree *)malloc(sizeof(struct topic_tree));
root->id = -1;
topic_tree *x = (topic_tree *)malloc(sizeof(struct topic_tree));
x->id = 5;
root->children["first"]=x;

但是这个:root-&gt;children["first"] = x; 给了我一个Floating point exception,我不知道为什么..

【问题讨论】:

  • topic_tree *root = (topic_tree *)malloc(sizeof(struct topic_tree)); -- 你为什么在 C++ 程序中使用malloc?这是完全错误的。 C++ 不是 C。
  • 打开你的 C++ 书籍到解释如何使用 newdelete 的章节并阅读它。我很好奇:在不知道newdelete 的情况下,您究竟是如何了解std::unordered_maps 和其他高级C++ 库容器的?哪本 C++ 教科书把你直接扔进了容器,没有讲授动态内存分配的基础知识?
  • 理想情况下,如果可以的话,完全避免手动分配内存。考虑改用unordered_map&lt;std::string, topic_tree&gt;。此外,您对结构使用 typedef 是一种 C 主义,在 C++ 中不是必需的。
  • 没有。 new 返回一个指向新对象的指针。我的印象是你是一个 C 程序员,他的印象是 C++“足够接近”。那不是真的。 C++ 具有 C 没有的类型类别,即非 POD 类型。你不能乱扔mallocmemcpy,或者它们上面的任何低级C函数。
  • 你不能指望没有教科书就学习 C++,对不起。 C++ 是当今使用的最复杂的通用编程语言。我已经使用 C++ 超过 20 年了,而且我还在学习。如“今天”。这只是事实。如果您尝试将随机 Google 搜索和 Youtube 视频中的一些 C++ 知识拼接在一起,您只会感到困惑。我不能给你一个链接,因为不存在这样的链接。没有任何链接会影响您获得大量 C++ 知识,这只能来自教科书,以及正式、严谨的研究。

标签: c++ stl floating-point unordered-map


【解决方案1】:

原因是在分配 topic_tree 结构后,您并没有对其进行初始化。
所以std::unordered_map 正在处理不起作用的未初始化内存。

使用new/delete的最佳解决方案

通常在 C++ 应用程序中,您应该避免使用 malloc/free。而是使用 newdelete 运算符,这将在构造时自动调用对象构造函数,
和析构函数。
像这样分配节点时:new topic_tree{} 你应该没问题。

如果您需要使用malloc/free

如果您想坚持使用 malloc,则必须显式调用构造函数。
这可以这样完成:

new (root) topic_tree{};

但请注意,为了free 需要调用析构函数的对象!

root->~topic_tree();

注意:如果您在代码中看到这种情况,通常是代码异味!
它的应用程序很少!

现代解决方案(使用智能指针进行内存管理)

在现代 C++ 项目中,您几乎看不到任何 newdelete 语句。
您可以使用智能指针代替对象分配,例如
std::unique_ptrstd::shared_ptrstd::auto_ptr 也是如此,但有点不同)。
这些容器将自动管理对象的生命周期,因此您完全不必担心。

【讨论】:

  • 非常感谢!另外,如何使用 Classes 创建我想要的结构?
  • new 运算符适用于结构和类。为了创建一个类,只需将结构关键字交换为类关键字。请注意,默认情况下,类成员可见性是私有的,而不是默认结构成员可见性是公共的。
  • 也许值得一提的是,对于编写惯用的 C++,您通常不需要任何这些;) 相当智能的指针并且不需要手动内存处理
  • @idclev463035818 你能再解释一下吗?
  • @C.Cristi 我指的是“如果你想坚持使用 malloc”。您很少需要求助于malloc。答案没有错,但几乎没有理由在 C++ 中使用 malloc,也几乎没有理由在可以使用智能指针时使用 new 并处理原始拥有指针
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多