-
Exception Error
I am doing a tree search generation but I have an issue with the 2 functions below.
The functions are used to determine old nodes on the tree in order to stop further exploration.
Function "isOld" is used to detect if there are already explored nodes with the same state information as the current node. It calls function "addInfo" to retrieve the list of tokens for already explored nodes.
The issue here is: an exception error (first and second chance) occurs on line "return conjCodis;" that copies the node information to vector "codis".
"First chance exception 0xC0000005 ACCESS_VIOLATION occurred at 0x00427D77, write of address 0x00000008 at 0x00427D77First chance exception 0xC0000005 ACCESS_VIOLATION occurred at 0x00427D77, write of address 0x00000008 at 0x00427D77
and a Second chance exception on the same line."
The error points to the "copy construct" of the vector.
The code works pretty well for smaller trees but gives error on that line for longer time run (larger trees), that takes more than 12 hours since I have tree generation problems that can take more than 2 days to run.
I used a 3rd party software to debug the code since it is not possible to run line debug for the time duration.
Your help would be greatly appreciated. Ideas on what to do and a better way to do this are welcomed.
Code:
vector<double> Tree::isOld(vector<TokenTree*> *tok, int trans, double codi) const
{
vector<double> interseccio;
vector<double> codis = conjPlaces.at(0)->addInfo(tok->at(0),codi);
int i=0;
interseccio=codis;
for(i=1; i< tok->size(); i++)
{
codis = conjPlaces.at(i)->addInfo(tok->at(i),codi);
int j = 0;
vector<double>::iterator posIter = interseccio.begin();
while(posIter!=interseccio.end())
{
vector<double>::iterator posicio = find(codis.begin(),codis.end(),*posIter);
if(posicio==codis.end()){
posIter = interseccio.erase(posIter++);
}
else
++posIter;
}
}
return interseccio;
}
Code:
vector<double> Place::addInfo(TokenTree *marca, double codi)
{
vector<double> conjCodis;
TreeToken tokAux = *marca;
map<TreeToken,vector<double> ,ltstr>::iterator pos = marcatges.find(tokAux); //marcatges is the data structure that stores the tokens for each node.
if(pos!=marcatges.end())
{
marca = const_cast<TreeToken*> (&((*pos).first));
conjCodis = marcatges[*marca];
marcatges[*marca].push_back(codi);
}
else
{
marcatges[*marca].push_back(codi);
}
return conjCodis;
}
-
-
You have a local vector being allocated when addinfo gets called, and you are returning it to the caller, but it goes away when the function ends. Don't do that. "New up" a vector, and return it instead.
-
Thanks for the suggestion(new the return vector). It worked on that part but led to another access violation on the vector that is being modified within the loop (interseccio) in the function. I remodified the function Tree::isOld a little.
It returns the access violation error on line "vector<double>::iterator posIter = interseccio.begin();
" (operation=,_UCopy, construct) after a long time run.
I checked to see if the issue was an empty vector but that didn't help.
Code:
if(!interseccio.empty())
posIter = interseccio.begin();
else
break;
Thanks for your help as usual.
Code:
void Tree::isOld(vector<TokenTree*> *tok, int trans, double codi, vector<double> interseccio) const
{
vector<double> codis;
interseccio = *(conjPlaces.at(0)->addInfo(tok->at(0),codi));
int i=0;
for(i=1; i< tok->size(); i++)
{
codis = *(conjPlaces.at(i)->addInfo(tok->at(i),codi));
vector<double>::iterator posIter = interseccio.begin();
while(posIter!=interseccio.end())
{
vector<double>::iterator posicio = find(codis.begin(),codis.end(),*posIter);
if(posicio==codis.end()){
posIter = interseccio.erase(posIter);
}
else
++posIter;
}
}
}
-
-
-
The difference between the first set of codes and the last one is just the return vector which i have done here (see below). Am I doing something wrong? Thanks for your help.
Code:
vector<double>* Place::addInfo(TokenTree *marca, double codi)
{
vector<double>* conjCodis = new vector<double>();
TreeToken tokAux = *marca;
map<TreeToken,vector<double> ,ltstr>::iterator pos = marcatges.find(tokAux); //marcatges is the data structure that stores the tokens for each node.
if(pos!=marcatges.end())
{
marca = const_cast<TreeToken*> (&((*pos).first));
conjCodis = &marcatges[*marca];
marcatges[*marca].push_back(codi);
}
else
{
marcatges[*marca].push_back(codi);
}
return conjCodis;
}
-
Can someone help me on this issue? I am running out of ideas...
-
I don't really see how allocating a vector on the heap and returning it would make any difference, since you're returning a copy of it.
The only thing I can think of right now is maybe you're running out of memory? You say it runs for a very long time, so maybe after a while, there's not enough contiguous memory left. Try catching a std::bad_alloc exception and see if that's what it is.