# /= doesn't do what you think it does?

This is a discussion on /= doesn't do what you think it does? within the C++ Programming forums, part of the General Programming Boards category; It will make sense once you're done reading... Code: for ( ...k++) for (int i = 0; i <= argc-3; ...

1. ## /= doesn't do what you think it does?

It will make sense once you're done reading...

Code:
```for ( ...k++)
for (int i = 0; i <= argc-3; i++){
cout << kFmap[k][namesmap[i]] << " kFmap | ";
cout << F[kFmap[k][namesmap[i]]] << " | ";
F[kFmap[k][namesmap[i]]] /= argc-2;
cout << F[kFmap[k][namesmap[i]]];
cout << endl;
}```
I would have something like this as result:

F(before /=) probability(Fafter /=)
1 0.10
1 0.10
1 0.10
3 0.30
1 0.10
1 0.10
3 0.03 --> It took the value above, 0.3, and divided it by the total
1 0.10
1 0.10
1 0.10

..so it took the probability twice on the second value that was the same as a value already calculated! Whats the deal with this? Logically, F[kFmap[k][namesmap[i]]] /= argc-2, should replace the current value of each F value with the divided by (argc-2) value of the current F. Why is it doing dividing the the n-1 value of F for the calculation of F(n). This behavior seems to be recursive as I get multiple divisions for multiple similar values. Removing the identical occuring values is planned but why am I seeing this weird behavior? This behavior may be limited to vectors.

This raises a concern. I want to create a function that takes a vector, and removes multiple occurances of members, like this: vectA = removecopies(vectA). This may not work since vectA is made to equal a called(and modified) instance of itself. Is this the case?

2. I suggest that you post the smallest and simplest compilable program that demonstrates the problem.

3. Originally Posted by laserlight
I suggest that you post the smallest and simplest compilable program that demonstrates the problem.
I'm trying,

cout << F[kFmap[k][namesmap[i]]] / (argc-2); worked as it should though, and all F[kFmap[k][namesmap[i]]] values are legit. I tried storing F[kFmap[k][namesmap[i]]] / (argc-2) in an intermediate variable and then make F[kFmap[k][namesmap[i]]] = midvar, casting everything to float, but that failed too.

4. Originally Posted by laserlight
I suggest that you post the smallest and simplest compilable program that demonstrates the problem.
I don't know if this is possible as this calls multiple classes, which call various libs. But could you tell me about how vectors store values [in detail, i.e memory allocation]? Somehow the program mistakes the percentage calculation of F[n-1] to be F[n], and theres no reason for this as the loop begins a new instance each run. I'm compiling g++ with ansi option and I'm getting no warnings. ansi conforms to ISO C90, but not C99 as it is a work in progress, I'll try passing C99 ansi flag...

F[ kFmap[k][ namesmap[i] ] ]

kFmap[k] is vector<map<string,int> > //returns an int
namesmap[i] is <string,int> , returns the string of truncated filenames of argv's
F[] is vector<int> //returns an int

5. I'm trying
Obviously, I cannot compile and run your code. In the meantime, I can only guess what kFmap, namesmap and F (F? That is a terribly undescriptive name!) are. My guess is that you are looking at a problem with integer division or floating point inaccuracy, but I am not good enough to determine anything given your code snippet.

7. But could you tell me about how vectors store values [in detail, i.e memory allocation]?
Since vectors are required to store their elements contiguously, they pretty much always use an internal dynamically allocated array. Quoting from Josuttis' The C++ Standard Library: "Inserting or removing elements invalidates references, pointers, and iterators that refer to the following elements. If an insertion causes reallocation, it invalidates all references, iterators, and pointers."

I don't know if this is possible as this calls multiple classes, which call various libs.
...
Somehow the program mistakes the percentage calculation of F[n-1] to be F[n], and theres no reason for this as the loop begins a new instance each run.
So, are you sure that the problem is not elsewhere? Maybe you have a bug elsewhere, and a bug in this code, and the interaction between those two bugs are producing the current problem. Basically, you need to isolate this current code such that you can determine that it really works (and ideally write unit tests for it). If that does not fix the problem, then there is probably another bug elsewhere that needs to be fixed.

8. Originally Posted by laserlight
Since vectors are required to store their elements contiguously, they pretty much always use an internal dynamically allocated array. Quoting from Josuttis' The C++ Standard Library: "Inserting or removing elements invalidates references, pointers, and iterators that refer to the following elements. If an insertion causes reallocation, it invalidates all references, iterators, and pointers."

So, are you sure that the problem is not elsewhere? Maybe you have a bug elsewhere, and a bug in this code, and the interaction between those two bugs are producing the current problem. Basically, you need to isolate this current code such that you can determine that it really works (and ideally write unit tests for it). If that does not fix the problem, then there is probably another bug elsewhere that needs to be fixed.
iso c++98 doesn't tell me anything. everything works fine except for that one line, I have made sure that all the vals are in their right place, havent I? I've shown what the values of F are before the /= operation. Whatever happens before this point is redundant.

"Inserting or removing elements invalidates references, pointers, and iterators that refer to the following elements." --> I guess this explains it doesn't it? "and iterators".

Its bad luck for me that this shocking that this effect is recursive, although quite unprobable to start with. Same goes for the fact that iso c98 doesn't cover this issue. Right? I have made this sample program, but it works fine:

Code:
```#include <iostream>
#include <vector>
using namespace std;

int main(){
vector<int>	A;
A.resize(10);
A[0] = 10;
A[1] = 20;
A[2] = 30;
A[3] = 40;
A[4] = 50;
A[5] = 10;
A[6] = 10;
A[7] = 80;
A[8] = 90;
A[9] = 100;

for (int i = 0; i < 10; i++){
cout << A[i] << " | ";
A[i] /= 10;
cout << A[i] << endl;
}
return 0;
}```
To be fully accurate I would have to emulate the entire sequence of events of things being passed from container to container. But, I fail to understand how this is necessary. Containers should only keep track of their assigned values - not how it was assigned in the container where it came from.

9. I have made sure that all the vals are in their right place, havent I? I've shown what the values of F are before the /= operation
I don't know, since your code snippet does not correspond to your example output.

"Inserting or removing elements invalidates references, pointers, and iterators that refer to the following elements." --> I guess this explains it doesn't it? "and iterators".
I don't know, just given the information at hand.

Same goes for the fact that iso c98 doesn't cover this issue. Right?
The 1998 version of the C++ Standard does not guarantee that vectors store their elements contiguously. On the other hand, this is fixed in the 2003 version of the C++ Standard, and it is highly unlikely that any sane standard library implementation would have implemented vectors such that they comply with C++98 but do not comply with C++03.

To be fully accurate I would have to emulate the entire sequence of events of things being passed from container to container.
What you can do is to populate F, kFmap and namesmap with test data, then use them in this part of the code. When you show us this test program, show everything, from the population of the containers to both of the loops to the exact output. Do not truncate anything, do not change anything, not even the sample output.

10. what is the g++ parameter for iso c++03? I don't think there is one (according to the man page).

11. what is the g++ parameter for iso c++03? I don't think there is one (according to the man page).
You're barking up the wrong tree. I am certain that g++ is not so brain damaged as to implement vector such that it does not comply with C++03. If it did, then it would have been filed as a bug more than 5 years ago.

Looking at your example, it is obvious that no reference, pointer or iterator can be invalidated. We're talking about things like this:
Code:
```#include <iostream>
#include <vector>

int main()
{
std::vector<int> vec(1, 123);
int& r = vec[0];
std::cout << vec[0] << " == " << r << std::endl;
vec.resize(vec.capacity() + 1); // r is invalidated
vec[0] = 456;
std::cout << vec[0] << " == " << r << std::endl;
}```

12. I have simplified code to demonstrate my example, please feel free to extend it to wider sets.

edit: fixed that annoying error message at the end.

Code:
```#include <iostream>
#include <vector>
#include <map>
using namespace std;

int main(){
vector<vector<float> > kF;
vector<float> F;
map <int, string> namesmap;

namesmap[1] = "one";
namesmap[2] = "two";
namesmap[3] = "three";
namesmap[4] = "four";

vector<map<string,int> > kFmap;
kFmap.resize(2);
kFmap[0][namesmap[1]] = 5;
kFmap[0][namesmap[2]] = 10;
kFmap[0][namesmap[3]] = 5;
kFmap[0][namesmap[4]] = 20;

kFmap[1][namesmap[1]] = 5;
kFmap[1][namesmap[2]] = 5;
kFmap[1][namesmap[3]] = 5;
kFmap[1][namesmap[4]] = 20;

for (unsigned int k = 0; k < 2; k++){
cout << "k = " << k << endl;
F.resize(6);
for (int i = 1; i <= 4; i++){
F[kFmap[k][namesmap[i]]]++;
}
for (int i = 1; i <= 4; i++){
cout << kFmap[k][namesmap[i]] << " kFmap | ";
cout << F[kFmap[k][namesmap[i]]] << " | ";
F[kFmap[k][namesmap[i]]] /= (10); //bug
cout << F[kFmap[k][namesmap[i]]] << " | ";
cout << endl;
} cout << endl;
kF.push_back(F);
F.clear();
}
return 0;
}```

13. Originally Posted by laserlight
You're barking up the wrong tree. I am certain that g++ is not so brain damaged as to implement vector such that it does not comply with C++03. If it did, then it would have been filed as a bug more than 5 years ago.

Looking at your example, it is obvious that no reference, pointer or iterator can be invalidated. We're talking about things like this:
Code:
```#include <iostream>
#include <vector>

int main()
{
std::vector<int> vec(1, 123);
int& r = vec[0];
std::cout << vec[0] << " == " << r << std::endl;
vec.resize(vec.capacity() + 1); // r is invalidated
vec[0] = 456;
std::cout << vec[0] << " == " << r << std::endl;
}```
I was referring to pointers as the possible pointers that exist within the vector or map class during its operation.

14. Given the complexity of your original post, I'm going to assume that this is part of some much larger program.

When dealing with apparent memory corruption, there is always a "cause" and an "effect".

For simple bugs, like say
a = 42 / 0;
the cause and effect are in the same place. As soon as the bug happens, you get to know about it.

Memory corruption on the other hand is much trickier.

In short, excessive analysis of where the problem appears (the effect) isn't going to help you understand the real problem (the cause). The true cause of the problem could be in a completely different area of the code.

If you extract this code, put a minimal support environment around it, and it works, then you can be pretty sure the real problem is somewhere else.

15. Upon further research, it appears that c++99 isn't fully supported. Some of 03 is supported, but you still pass the 99 flag to it, and it says you can also use -pedantic but it won't tell you which of 03 is in passing -c++99 and which is in pedantic.

Page 1 of 4 1234 Last