【问题标题】:c++ : error: taking address of temporary [-fpermissive]c ++:错误:获取临时地址[-fpermissive]
【发布时间】:2020-04-05 18:24:18
【问题描述】:

我正在尝试用二叉树做一些实验。我运行了以下代码:

#include<iostream>

using namespace std;

struct tree{
   char data;
   tree *left=NULL;
   tree *right=NULL;
   tree *parent=NULL;
};   


tree newNode(char d)
{
   struct tree node;
   node.data = d;
   return node;
}
int main()
{

   struct tree currentNode = newNode(' ');
  currentNode.left = &newNode(' ');
         return 0;
}

我收到此错误:

error: taking address of temporary [-fpermissive]

currentNode.left = &newNode(' ');

是什么导致了这个错误,我该如何纠正这个错误?

【问题讨论】:

  • 您必须使用new 或类似的方式分配节点。 struct tree node; 在您退出函数时被删除,并且您返回的副本在您调用函数的行尾(大致)被删除,因此即使编译器允许您在此处获取地址,您会得到一个悬空指针。
  • 您不能将临时对象绑定到指针。对于这种 if 结构,最简单的做法是动态分配节点。另外,如果您想学习 C 语言,那很酷,但我会使用 C 编译器。学习神话般的 c/c++ 语言是一个错误。如果你真的在学习 c++,那就烧掉你正在使用的资源并找到更好的资源吧:)。
  • @HolyBlackCat 我应该在这段代码中改变什么?

标签: c++


【解决方案1】:

函数的返回值称为临时值。临时对象只存在很短的时间,所以如果你想用临时对象做某事,那么你必须在它被销毁之前立即做。但是您正在获取临时地址,这意味着您的程序将有一个指向已销毁对象的指针。所以你的程序很可能会崩溃。

这样做的方法是动态内存分配。现在很明显你在学校或大学,所以他们一定是想教你这个话题。这个话题太大了,无法在这里解释,所以我建议你回到你的笔记或你最喜欢的 C++ 书籍并研究动态内存分配。

但这里是快速修复代码的方法

tree* newNode(char d)
{
   tree* node = new tree; // dynamically allocate a node
   node->data = d;
   return node;
}

int main()
{
    tree* currentNode = newNode(' ');
    currentNode->left = newNode(' ');
}

如果你理清了节点和树之间的区别,你的代码(和你的想法)也会得到很大的改进。它们不是同一件事。您的struct tree 实际上是一个节点,所以它的名称完全错误。

顺便说一句,注意编译器警告消息做得很好。大多数新手不这样做,他们只是对编译的代码感到高兴。在这种情况下,警告消息表明您的代码存在严重问题。

【讨论】:

  • 这不是警告。这是一个硬错误。语言不允许取右值的地址。
【解决方案2】:

表达式newNode(' ') 创建一个临时的tree 对象,如错误消息所示。这是一个对象,它的生命周期仅限于它出现的语句。这意味着,超过该分号,该对象将不再存在。

对于您正在执行的结构类型,您可能需要动态内存分配。这样做的一种()方法是tree* ptr = new tree;(在 newNode 中)。这很糟糕,因为如果您不小心编写适当的析构函数,它可能会泄漏资源。最好在 tree 类中使用 unique_ptr 作为指针:

#include <memory>

struct tree{
   char data;
   std::unique_ptr<tree> left = nullptr;
   std::unique_ptr<tree> right = nullptr;
};

然后:

currentNode.left = std::make_unique<tree>(' ');

如果您必须有一个parent 指针,则必须使用std::shared_ptrstd::weak_ptr 的组合来避免shared_ptr 循环。

struct tree {
   char data;
   std::shared_ptr<tree> left = nullptr;
   std::shared_ptr<tree> right = nullptr;
   std::weak_ptr<tree> parent = nullptr;
};

另请注意:Why is "using namespace std;" considered bad practice?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多