Why does the content of a pointer change? - c++

I'm a C# programmer and now using C++ to do some work.
pair<Point,double>* p=NULL;
Sphere* sphere=NULL;
for (int i=0;i<spheres.size();i++)
{
vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]);
if(solution.size()==0)
continue;
if(p==NULL || solution[0].second<p->second)
{
p=&solution[0];
sphere=&spheres[i];
}
}
if(p==NULL)
return backgroundColor;
else
{
Color c=localIlluminate(p->first,*sphere);
return c;
}
I want p.first to have the smallest value, and sphere be the cooresponding sphere that is used to get p.
After debugging, I find the code doesn't work. In the first loop, p will be assigned the address of solution[0], assuming the value is {(0,0),0}. Then the loop continues and when i=1, assume solution[0] becomes {(1,2),3} and value of p also becomes {(1,2),3}.
I don't expect the value of p to change. How should I fix it?

You are storing the reference to a local variable outside the scope in which the local variable is declared.
Every iteration solution is not valid anymore, then the address to it shouldn't be considered valid. To obtain what you need you should assign the variable by value, so that you actually copy the contained value, eg:
pair<Point, double> p = std::make_pair(whatever, std::numeric_limits<double>::max());
for (...)
{
if (solution[0].second < p.second)
p = solution[0];
}
The fact that the address changes can be caused by multiple reasons, but you shouldn't bother understanding why, just avoid this kind of situation. Your misconception comes from the fact that C# has a garbage collection which prevents solution[0] from becoming invalid, which is not true for C++, when variable are declared on stack.

When you assign to p it points to the adresss of &solution[0] but on the next iteration of the loop that variable goes poof and a new one gets created and p points to either random stuff or something else.
It might be better to just store a copy in p, so make p a regular variable and copy over the solution[0] by assigning. You can have another bool variable to determine if a solution was found.
pair<Point,double> p;
Sphere sphere;
bool solutionFound = false;
for (int i=0;i<spheres.size();i++)
{
vector<pair<Point,double>> solution=findIntersection(Point(ray.origin),Point(ray.direction.x,ray.direction.y,ray.direction.z),spheres[i]);
if(solution.size()==0)
continue;
if(!solutionFound || solution[0].second < p.second)
{
p=solution[0];
sphere=spheres[i];
solutionFound = true;
}
}
if(!solutionFound)
return backgroundColor;
else
{
Color c=localIlluminate(p.first, sphere);
return c;
}

Related

Cannot dereference double pointer, " no match for operator* "

I'm trying to search through an array of pointers to objects of class Shape. I have written the following code. However, I'm getting this error: "no match for operator*", and I don't know where to go from here. Any help is appreciated.
Shape** shapesArray;
bool doesNameExist(string name) {
for (int i = 0; i < shapeCount; i++)
{
if(*(shapesArray[i])->getName() == name)
{
return true;
}
else
{
return false;
}
}
}
shapesArray is a Shape**
shapesArray[i] is Shape*
(shapesArray[i])->getName() is dereferencing shapesArray[i] and calls its
member getName
So far nothing wrong. I guess this is what you actually want to get, but you add another *:
*(shapesArray[i])->getName() tries to dereference what was returned from getName (a std::string perhaps?)
PS: You return from the loop in the first iteration in either case. If you want to search in the array you need to loop until you find it (then return true) or loop till the end (then return false after the loop, because it wasn't found).

Problems implementing recursive best-first search in C++ based on Korf 1992

I am having two main issues implementing the algorithm described in this article in C++: properly terminating the algorithm and freeing up dynamically allocated memory without running into a seg fault.
Here is the pseudocode provided in the article:
RBFS (node: N, value: V, bound: B)
IF f(N)>B, return f(N)
IF N is a goal, EXIT algorithm
IF N has no children, RETURN infinity
FOR each child Ni of N,
IF f(N) < V AND f(Ni) < V THEN F[i] := V
ELSE F[i] := f(Ni)
sort Ni and F[i] in increasing order of F[i]
IF only one child, F[2] := infinity
WHILE (F[1] <= B)
F[1] := RBFS(N1, F[1], MIN(B, F[2]))
insert N1 and F[1] in sorted order
return F[1]
Here, f(Ni) refers to the "computed" function value, whereas F[i] refers to the currently stored value of f(Ni).
Here is my C++ implementation, in which I had to use a global variable to keep track of whether the goal had been reached or not (note, I am trying to maximize my f(n) value as opposed to minimizing, so I reversed inequalities, orders, min/max values, etc.):
bool goal_found = false;
bool state_cmp(FlowState *lhs, FlowState *rhs)
{
return (lhs->value > rhs->value);
}
int _rbfs(FlowState *state, int value, int bound)
{
if (state->value < bound) // Returning if the state value is less than bound
{
int value = state->value;
delete state;
return value;
}
if (state->is_goal()) // Check if the goal has been reached
{
cout << "Solved the puzzle!" << endl;
goal_found = true; // Modify the global variable to exit the recursion
return state->value;
}
vector<FlowState*> children = state->children();
if (children.empty())
{
//delete state; // Deleting this state seems to result in a corrupted state elsewhere
return INT_MIN;
}
int n = 0; // Count the number of children
for (const auto& child: children)
{
if (state->value < value && child->value < value)
child->value = value;
else
child->update_value(); // Equivalent of setting stored value to static value (F[i] := f(Ni))
++n;
}
sort(children.begin(), children.end(), state_cmp);
while (children.front()->value >= bound && !goal_found)
{// Loop depends on the global goal_found variable since this is where the recursive calls happen
if (children.size() < 2)
children.front()->set_value(_rbfs(children.front(), children.front()->value, bound));
else
children.front()->set_value(_rbfs(children.front(), children.front()->value, max(children[1]->value, bound)));
}
// Free children except the front
int i;
for (i = 1; i < n; ++i)
delete children[i];
state->child = children.front(); // Records the path
return state->child->value;
}
void rbfs(FlowState* initial_state)
{
// This is the actual function I invoke to call the algorithm
_rbfs(initial_state, initial_state->get_value(), INT_MIN);
print_path(initial_state);
}
My main questions are:
Is there a way to terminate this function than having to use a global variable (bool goal_reached) without a complete re-implementation? Recursive algorithms usually have some kind of base-case to terminate the function, but I am not seeing an obvious way of doing that.
I can't seem to delete the dead-end state (when the state has no children) without running into a segmentation fault, but not deleting it results in unfreed memory (each state object was dynamically allocated). How can I modify this code to ensure that I've freed all of the states that pass through it?
I ran the program with gdb to see what was going on, and it appears that after deleting the dead-end state, the next state that is recursively called is not actually NULL, but appears to be corrupted. It has an address, but the data it contains is all junk. Not deleting that node lets the program terminate just fine, but then many states aren't getting freed. In addition, I had originally used the classical, iterative best-first search (but it takes up far too much memory for my case, and is much slower), and in that case, all dynamically allocated states were properly freed so the issue is in this code somewhere (and yes, I am freeing each of the states on the path in main() after calling rbfs).
In your code, you have
children.front()->set_value(_rbfs(children.front(), ...
where state inside of _rbfs is thus children.front().
And in _rbfs, you sometimes delete state. So children.front() can be deleted and then called with ->set_value. There's your problem.
Is there any reason why you calling delete at all?

Unexplained Behavior with std::vector

In Stepping through some weird segmentation fault causing code, I found that after the assignment of one vector to another, the receiving vector arbitrarily corrupts. The following is a code snippet from a copy constructor of a class which has a data member vector<Piece> *pieces which is a dynamically allocated array containing vectors of type Piece.
ClassName::ClassName(const Class &other) // copy constructor of class
{
...
for(SIDE_t s = 0; s < sides; s++)
{
pieces[s].reserve(other.pieces[s].size());
pieces[s] = other.pieces[s]; //vector is completely valid here
for(Uint8 p = 0; p < pieces[s].size(); p++)
{
//it continues validity throughout loop
if(other.pieces[s][p].getCell() != NULL)
pieces[s][p].setCell(cells + (other.pieces[s][p].getCell() - other.cells));
if(pieces[s][p].getCell() == NULL)
out.push_back(&pieces[s][p]);
}
if(other.flags[s] != NULL)
flags[s] = getPiece(other.flags[s]->getValue(), other.flags[s]->getSide());
// vector is invalid in scope of getPiece, which receives completely valid arguments
else
flags[s] = NULL;
}
}
Piece * const ClassName::getPiece(const Uint8 num, const SIDE_t s) const
{
return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
// Right here during the member access function of pieces,
// it is clear that the vector was corrupted some how
}
Essentially during debugging, I would step into pieces[s] member access function. In the loop body, it is evident that m_start has a valid address, however when it exits the loop body and calls the index operator on pieces[s] in getPiece, m_start is NULL. There are no operations performed on pieces[s] between the last iteration of the loop when m_start is valid, and in getPiece when during the same call of the index operator as in the loop body, m_start is NULL. Any insight on my misuse of std::vector or bugs in std::vector would be appreciated.
It looks to me that you have an access violation here:
return (num>nPieces || s>sides || num == 0)? NULL:&pieces[s][num-1];
First (as pointed out by Petr), it should read s>=sides.
Second, s here is not the same as s in the caller. So pieces[s] may not have been assigned yet and is an empty vector. To test it use
return (num>nPieces || s>=sides || num == 0)? NULL : &(pieces[s].at(num-1));
Btw, all this would have been avoided had you simply used
std::vector<std::vector<Piece>>
and copied the whole thing.

Passing a pointer to enum to a function

I'm trying to pass an enum declared outside of a function's scope, to a function, so that changing the value of the enum within the function changes the value of the enum pointed to. Using the enum itself just in the scope of the object is not an option as I wish to use this function with multiple different instances of this enum.
I have an enum 'ColourState'. Declared like so. and a pointer to a ColourState.
enum ColourState {COLOUR1, COLOUR2};
ColourState* CS_GO_score;
The pointer was initialised like so.
CS_GO_score = new ColourState;
*CS_GO_score = ColourState::COLOUR2;
I'm now trying to pass the ColourState pointed to by CSS_GO_score to the function 'pulsateColour'
Like so.
void HUD::pulsateColour(GLfloat *colour1, GLfloat *colour2, GLfloat *objectCol, ColourState goingTo, int timeInFrames)
{
GLfloat difference[4];
//give us an array of values to change the array by in the alloted time
difference[0] = (colour1[0]-colour2[0])/timeInFrames;
difference[1] = (colour1[1]-colour2[1])/timeInFrames;
difference[2] = (colour1[2]-colour2[2])/timeInFrames;
difference[3] = (colour1[3]-colour2[3])/timeInFrames;
//depending on the state, transform the array in one direction or another
if(goingTo == ColourState::COLOUR2)//if we're moving toward colour 2
{
for(int i = 0; i<4; i++)
{
objectCol[i] -= difference[i];//subract the difference till we get there
//we need to SNAP to the colour as we will not hit it every time using floats
if( (objectCol[i]>(colour2[i]-(difference[i]*2))) && (objectCol[i]<(colour2[i]+(difference[i]*2))) )
{//if we hit this tiny but huuuge target
objectCol[i] = colour2[i];//SNAP
}
}
}else{
if(goingTo == ColourState::COLOUR1)
{
for(int i = 0; i<4; i++)
{
objectCol[i] += difference[i];//add the difference till we get there
//we need to SNAP to the colour as we will not hit it every time using floats
if( (objectCol[i]>(colour1[i]-(difference[i]*2))) || (objectCol[i]<(colour1[i]+(difference[i]*2))) )
{//if we hit this tiny but huuuge target
objectCol[i] = colour1[i];//SNAP
}
}
}
}
if((objectCol[0] == colour1[0])&&(objectCol[1] == colour1[1])&&(objectCol[2] == colour1[2])&&(objectCol[3] == colour1[3]))
{//if the objcolour == colour 1
goingTo = ColourState::COLOUR2;//it's now time to move towards colour 2
}else{
if((objectCol[0] == colour2[0])&&(objectCol[1] == colour2[1])&&(objectCol[2] == colour2[2])&&(objectCol[3] == colour2[3]))
{//if the objcolour == colour 2
goingTo = ColourState::COLOUR1;//it's now time to move towards colour1
}
}
}
}
This function is called like so.
pulsateColour(white,blue, GO_scoreColour, *CS_GO_score, 10);
However, when the value pointer to by 'goingTo' and 'CS_GO_score' (they should be the same address therefore technically the same object right?), watching the values monitor in VS i see that only the value pointed to by 'goingTo' (as it is local to the function) is changed? What am I doing wrong?
You are passing the enum by value, so the function has a local copy of whatever you pass it. If you want to pass an enum and modify it value, I suggest passing by reference.
enum ColourState {COLOUR1, COLOUR2};
void change_colour(ColourState& c)
{
c = COLOUR2;
}
....
ColourState cs = COLOUR1;
change_colour(cs);
However, when the value pointer to by 'goingTo' and 'CS_GO_score'
(they should be the same address therefore technically the same object
right?),
NO...
It will be the "same object" if you pass the pointer itself. Here you are passing the value pointed by the pointer. Alternatively you may want to pass a reference.
void HUD::pulsateColour(GLfloat *colour1,
GLfloat *colour2,
GLfloat *objectCol,
ColourState goingTo, /* pass by value */
int timeInFrames)
...
I'm trying to pass an enum declared outside of a function's scope, to
a function, so that changing the value of the enum within the function
changes the value of the enum pointed to.
You will need to change the funcion to take a pointer or a reference:
ColourState *goingTo, /* pass direct the pointer */
or
ColourState &goingTo, /* pass a reference-dont need to change the body of the function */

Array PopFront Method C++

Trying not to lose it here. As you can see below I have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront(int& nPopFront)
{
nPopFront = items[top+1].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
++intFrontPtr;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
return true;
}
In the else statement I'm simply reassigning to ensure that my ptrs are where I want them. For some reason I'm popping off the back instead of off the front.
Anyone care to explain?
I'm not entirely sure I understand what you're trying to do, but if I;m guessing right you're trying to 'pop' the 1st element of the array (items[0]) into the nPopFront int reference, then move all the subsequent elements of the array over by one so that the 1st element is replaced by the 2nd, the 2nd by the 3rd, and so on. After this operation, the array will contain one less total number of elements.
Not having the full declaration of the quack class makes most of the following guesswork, but here goes:
I'm assuming that item[0] represents the 'front' of your array (so it's the element you want 'popped').
I'm also assuming that 'count` is the number of valid elements (so item[count-1] is the last valid element, or the 'back' of the array).
Given these assumptions, I'm honestly not sure what top is supposed to represent (so I might be entirely wrong on these guesses).
Problem #1: your nPopFront assignment is reversed, it should be:
nPopFront = items[0].n;
Problem #2; your for loop is a big no-op. It walks through the array assigning elements back to their original location. I think you want it to look more like:
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
Finally, you'll want to adjust count (and probably top - if you need it at all) before you return to adjust the new number of elements in the data structure. The whole thing might look like:
bool quack::popFront(int& nPopFront)
{
if ( count >= maxSize ) return false;
if ( count == 0 ) return false; // nothing to pop
nPopFront = items[0].n;
intFrontPtr = &items[0].n; // do we really need to maintain these pointers?
intBackPtr = &items[count-1].n;
for (int i = 1; i < count; ++i)
{
items[i-1].n = items[i].n; // move elements from back to front
}
count -= 1; // one less item in the array
return true;
}
The original question seems to be that you don't understand why the function popFront returns 3 times when there are 3 elements?
If that's the case, I think you are missing the point of recursion.
When you make a recursive call, you are calling the same function again, basically creating a new stack frame and jumping back to the same function. So if there are 3 elements, it will recurse by encountering the first element, encountering the second element, encountering the third element, returning from the third encounter, returning from the second encounter, and returning from the first encounter (assuming you are properly consuming your array, which you don't appear to be).
The current function cannot return until the recursive call has iterated, thus it may appear to return from the last element before the second, and the second before the first.
That is how recursion works.
I wasn't able to make sense of your example, so I whipped one up real fast:
#include <iostream>
using namespace std;
bool popfront(int* ptr_, int* back_) {
cerr << ptr_[0] << endl;
if(ptr_ != back_) {
popfront(++ptr_, back_);
}
return true;
}
int main() {
int ar[4] = {4,3,2,1};
popfront(ar, ar + 3);
return 0;
}
That's not great, but it should get the point across.
Can't you just use a std::list?
That makes it really to pop from either end using pop_front or pop_back. You can also add to the front and the back. It also has the advantage that after popping from the front (or even removing from the middle of the list) you don't have to shift anything around (The link is simply removed) which makes it much more efficient than what you are, seemingly, proposing.
I'm assuming you're trying to assign the popped value to nPopFront?
bool stack::popFront(int& nPopFront)
{
//items[4] = {4,3,2,1}
if ( intFrontPtr < intBackPtr )
{
nPopFront = *intFrontPtr;
++intFrontPtr;
}
return true;
}
bool quack::popFront(int& nPopFront)
{
if(items.n==0) throw WhateverYouUseToSignalError;
nPopFront = items[0];
for (int =0;i<items.n-1,++i){
items[i]=items[i+1]
}
//update size of items array
}