I’m not sure what I’m doing wrong, but two versions of code that should give the same results are giving different results. If anyone could explain what is going on, I would really appreciate it.
The situation is as follows. I am working with arrays as ‘vectors’ and I have a simple function sub with two overloads to calculate the difference between the two vectors. The first basically calculates v := v - w, while the second calculates x := v - w.
// Subtract w[] from v[]
template <class T>
void sub(T *v, T *w, short m)
{
for (short r = 0; r < m; r++)
v[r] = v[r] - w[r];
}
// Subtract w[] from v[] and store result in x[]
template <class T>
void sub(T *v, T *w, T *x, short m)
{
for (short r = 0; r < m; r++)
x[r] = v[r] - w[r];
}
Now at some point I need to calculate v - w, and if it satisfies some condition, replace v by v - w. If not, v should remain unchanged. At first I had
...
// temp := v - w
sub<T>(v, w, temp, m);
if (condition on temp)
{
// v := v - w
sub<T>(v, w, m);
}
...
To improve efficiency, I figured it would be a waste to calculate the same thing twice, so I replaced the above by
...
// temp := v - w
sub<T>(v, w, temp, m);
if (condition on temp)
{
// swap v and temp
std::swap(v, temp);
}
...
The variable temp is in fact reused after, which could cause problems, but every time I first call sub<T>(v, w, temp, m); (thus erasing all content in the array) before using temp again.
Now after doing the above replacement, the results of my algorithm suddenly change. If anyone could explain why the results change and what is happening, I would be very grateful!
Thanks in advance.
Edit
A quick check shows that in both cases, in each iteration, the final value of v and the initial value of temp is the same. So the functions are doing what they are supposed to do…
The only possibility I can think of explaining the odd behavior is that for some reason, the function std::swap is using randomness, leading to different results. I’m using the same seed for each run and should get the same results each time, but if std::swap uses rand() somewhere, that would explain the different results. But I have no idea why this function would use rand().
It turns out that at that point in the code, “the damage was already done”. The swapping was done inside a function
bla, which tookvas an argument, as followsBut today I learned that this way, the function
blaonly makes a local copy of the pointer and works with that, instead of using the actual address with the actual pointer stored in the memory. So instead of swapping the globalvwithtemp, I was swapping a localvwithtemp, and so this did not affect the globalv. This also explains why I did not notice any problems locally, as inside the function,vindeed behaves the way it should. So at that point in the code, the only way to swap the values would be recomputing the expression.A simple solution works: change the function declaration to
void bla(..., T*& v, ...), so that the local copy ofvused in the functionblaactually corresponds to the same physical memory address as the globalv. Thenstd::swap()works fine.