So I'm having a bit of SegFaults and was wondering if someone can explain me in higher depth how does this work.
I have a wrapper class around a numeric variable, and I'm trying to build a compute tree of the expression. Here is a sample code:
class DoubleWrap{
public:
static int id;
DoubleWrap(double value){this->value = value;myid=++id;}
double value;
int myid;
std::vector<DoubleWrap*> parents;
DoubleWrap operator+(DoubleWrap& x){
DoubleWrap result(this->value + x.value);
setParents(*this,result);
setParents(x,result);
return result;
}
void setParents(DoubleWrap& parent,DoubleWrap& child){
child.parents.push_back(&parent);
}
void printTree(){
std::cout<< "[" << this->myid << "]-(";
for (auto& elem: this->parents)
std::cout<< elem->myid << "," << elem <<",";
std::cout<<")"<<std::endl;
for (auto& elem: this->parents)
elem->printTree();
}
}
The problem I got is for an expression like x = a+b+c+d; When I try to look for the parents of x, it has 2 parents, but parents[0].parents[0] is nil, e.g. for some reason the pointer to the allocated place does not work or the allocated memory is destroyed?
I'm quite interested if anyone can advise me on a workaround and why this happens.
To give an example on this code:
DoubleWrap dw(12.6);
DoubleWrap dw2(12.5);
DoubleWrap dw3(12.4);
DoubleWrap dw4(12.3);
DoubleWrap a = dw + dw2 + dw3;
DoubleWrap b = a + dw+ dw2+ dw3 + dw4;
b.printTree();
I expect the output:
[10]-(9,0x13a4b50,4,0x7fff5bdb62f0,)
[9]-(8,0x13a4b00,3,0x7fff5bdb62c0,)
[8]-(7,0x13a49f0,2,0x7fff5bdb6290,)
[7]-(6,0x7fff5bdb6320,1,0x7fff5bdb6260,)
[6]-(5,0x13a4db0,3,0x7fff5bdb62c0,)
[5]-(1,0x7fff5bdb6260,2,0x7fff5bdb6290,)
[1]-()
[2]-()
[3]-()
[1]-()
[2]-()
[3]-()
[4]-()
But the result I get (usually different on different runs):
[10]-(9,0x7ffffd5e2f00,4,0x7ffffd5e2de0,)
[9]-(33,0x1c6da10,3,0x7ffffd5e2db0,)
Process finished with exit code 139
My guess is that the return of the operator in fact copies the DoubleWrap variable, thus value to which the pointer in parents is pointing to goes out of scope and the memory is released?
The temporary solution was to return by reference, but the question is why and is there a proper one?
PS: Fixed a previous mistake I got which is a mistake in setParents.