C++ Taking address of temporary - error while assi

2019-06-05 02:11发布

问题:

This program is written in C++. I am trying to use a void function to expand a Line structure which consists of an integer length and a pointer to the next connected line. There is a void Expand function made to assign a line reference to the line pointer in the struct. The new line is to be double the size of the current line. With the code I am using, I get a g++ error of 'Taking address of temporary [-fpermissive]'. Could anyone suggest a way in which the function adds a valid instance of a line reference to the Line pointer 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;
}

回答1:

This one works

    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;
}


回答2:

You're trying to implement a linked list, but you don't understand manual memory management yet.

The short-term solution is to use std::list<Line>. There's already a solution that works, and you don't need to bother with the behind-the-scenes stuff.

The long-term solution also is to use std::list<Line>. No need to re-invent the wheel, even if you're a seasoned developer and know how to.



回答3:

The problem with the line:

lineRef.nextLine = &NewLine(lineRef);

is what the compiler is telling you. You are taking the address of a temporary. What it means is that after the ; is reached, the temporary NewLine(lineRef) will be destroyed and the pointer lineRef.nextLine will be pointer to a dead object.


Update: how to make it work.

It depends on what you want to do. If what you want is to have a list then the simplest thing is using a prepacked list data structure (std::list<Line>) rather than rolling your own implementation of list.

If you really want to implement your own list, then you will need to dynamically allocate the next node (this will make the compiler happy) and you will need to add code to manage the list (proper construction of the Line object that initializes the fields, including copy-construction, destructors to manage the dynamic memory, probably some helper functions to walk the list (or iterators to be able to use algorithms...) Just don't bother and use std::list.