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