I’m using a vector of pointers and the iterator that it comes with in C++. The way I originally wrote it would cause a seg fnault, but with a seemingly trivial change, declaring and initializing an unused variable the seg fault goes away. Does anyone know why?
Here’s the code that seg faults. The final line that successfully executes is line 8 (found via printf statements) and uncommeting line 4 get rids of the segfault:
1 Intersect RayTracer::closestShape(Ray r){
2 vector<Shape *>::iterator itStart = scene.getShapes().begin();
3 vector<Shape *>::iterator itEnd = scene.getShapes().end();
4 //vector<Shape *> sceneShapes = scene.getShapes(); This is the unused line that will cause the code to run successfully if I uncomment it.
5 Intersect closest = Intersect();
6 for(;itStart != itEnd; itStart++){
7 Intersect currentIntersect = (*itStart)->intersect(r);
8 if(currentIntersect.isHit()){
9 if(currentIntersect.getT() < closest.getT()){
10 closest = currentIntersect;
}
}
}
return closest;
}
And here’s the working version that no longer segfaults:
1 Intersect RayTracer::closestShape(Ray r){
2 vector<Shape *> sceneShapes = scene.getShapes();
3 vector<Shape *>::iterator itStart = sceneShapes.begin();
4 vector<Shape *>::iterator itEnd = sceneShapes.end();
5 Intersect closest = Intersect();
6 for(;itStart != itEnd; itStart++){
7 Intersect currentIntersect = (*itStart)->intersect(r);
8 if(currentIntersect.isHit()){
9 if(currentIntersect.getT() < closest.getT()){
10 closest = currentIntersect;
}
}
}
return closest;
}
If anyone could provide clarification as to why this is happening, that would be greatly appreciated! Please let me know if there’s anything I can add to clarify my problem.
vector<Shape *> sceneShapes = scene.getShapes();creates persistent object on the stack.itStartanditEndpoints to valid memory. In your first example iterators points to non-valid memory because they points to temporary object from callscene.getShapes()which had been immediately destroyed and invalidate your iterators.When you uncomment your
//vector<Shape *> sceneShapes = scene.getShapes();line it returns vector which is feet to same memory bounds as temporary was and iterators are valid again! But it is not 100% chance that it will be the same and you must be very careful to avoid such problems.