【问题标题】:C++ Taking address of temporary - error while assigning reference to pointerC ++在分配对指针的引用时获取临时地址 - 错误
【发布时间】:2012-02-13 15:48:32
【问题描述】:

这个程序是用 C++ 编写的。我正在尝试使用 void 函数来扩展 Line 结构,该结构由整数长度和指向下一条连接线的指针组成。有一个 void Expand 函数用于将行引用分配给结构中的行指针。新行的大小是当前行的两倍。使用我正在使用的代码,我得到一个 g++ 错误“获取临时 [-fpermissive] 的地址”。谁能建议一种方法,让函数将行引用的有效实例添加到 Line 指针 nextLine?

struct Line
{
    int length;
    Line* nextLine;
};

Line NewLine(Line& lineRef)
{
    Line newLine;
    newLine.length = lineRef.length * 2;
    return newLine;
}

void Expand(Line& lineRef)
{
    //Error here states: Taking address of temporary [-fpermissive]
    lineRef.nextLine = &NewLine(lineRef);
}

int main() {

    Line line;

    Expand(line);

    cout << line.length << endl;
    cout << line.nextLine->length << endl;

    return 0;
}

【问题讨论】:

    标签: c++ pointers struct


    【解决方案1】:

    您正在尝试实现一个链表,但您还不了解手动内存管理。

    短期解决方案是使用std::list&lt;Line&gt;。已经有一个可行的解决方案,您无需为幕后的事情操心。

    长期解决方案也是使用std::list&lt;Line&gt;。无需重新发明轮子,即使您是经验丰富的开发人员并且知道如何操作。

    【讨论】:

    • 我宁愿推荐vector作为基本数据结构而不是list
    • @MatthieuM.:因为...?在没有任何性能要求的情况下,我们当然无法从问题中找到的代码 sn-p 推断出,list 与 vector 一样好的容器。
    • @Darryl:因为 Stroustrup 是这么说的? vector 是容器的默认选项。除非您有指示其他数据结构的要求,否则请使用vector。它易于使用,并且提供了序列容器中最多的功能,最高兼容 C(这对初学者很重要,因为不幸的是教程中经常有令人作呕的 C 主义......)
    • 问题中的代码实现了一个链表;我不打算改变这一点。如果Line[N] 有问题,我推荐std::vector
    【解决方案2】:

    线路的问题:

    lineRef.nextLine = &NewLine(lineRef);
    

    是编译器告诉你的。您正在使用临时地址。意思是在到达;之后,临时的NewLine(lineRef)会被销毁,而指针lineRef.nextLine会指向一个死对象。


    更新:如何使其工作。

    这取决于你想做什么。如果您想要一个 list,那么最简单的方法是使用预打包的 list 数据结构 (std::list&lt;Line&gt;),而不是滚动您自己的列表实现。

    如果你真的想实现你自己的列表,那么你需要动态分配下一个节点(这会让编译器很高兴)并且你需要添加代码来管理这个列表(正确构造用于初始化字段的Line 对象,包括copy-construction、用于管理动态内存的析构函数,可能还有一些帮助函数遍历列表(或iterators 能够使用算法......)只是不要打扰并使用std::list

    【讨论】:

    • 我宁愿推荐vector作为基本数据结构而不是list
    【解决方案3】:

    这个有效

        struct Line
        {
                int length;
                Line* nextLine;
                ~Line(){delete nextLine;}
                 //Make copy constructor and assignment operator private
        };
    
        void Expand(Line* lineRef)
        {
                lineRef->nextLine = new Line;
                lineRef->nextLine->length = 2*(lineRef->length) ;
        }
    
    int main() 
    {
    
            Line* line = new Line;
            line->length = 5;
    
            Expand(line);
    
            cout << line->length << endl;
            cout << line->nextLine->length << endl;
    
            delete line;
            return 0;
    }
    

    【讨论】:

    • 请...不要!这起作用。它似乎可以在这个玩具示例中工作,但是如果您复制 Line 会严重崩溃,因为将复制 nextLine 指针,但不会复制它指向的内容,然后运行时将尝试在同一个指针上调用delete 两次。
    • 是的,复制构造函数和赋值操作符应该做一个深拷贝,或者它们应该是私有的。
    • 或者更简单的说,指针的所有权应该交给智能指针。 std::unique_ptr 在 C++11 中。
    • @MatthieuM.,我不太明白它是如何工作的。您能否详细说明或发布示例链接?
    • 为什么不接受这个响应:仅仅是一个 sn-p,需要额外的代码才能有用和稳定(包括更好地处理副本)。虽然我更喜欢其他答案作为解决方案,但这是一个有用的回复,可以帮助原始发帖人理解其原始问题背后的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多