This question already has answers here:
vector size - 1 when size is 0 in C++
(5 answers)
Closed 1 year ago.
I just run into a nasty bug where I have a loop
for (auto i = 0; i < vec.size() -1; ++i) {
//
}
with vec being an emtpy std::vector, thus vec.size() -1 evaluates to 2^64 on my system.
What's the correct way of writing the above loop?
size_t is an unsigned type hence the problem, just do that this way:
for (auto i = 0U; i + 1 < vec.size(); ++i)
0U added to make i unsigned (to avoid warning), but I would better use size_t istead of auto in this case
What's the correct way of writing the above loop?
Keep the loop as it is, but add an if-condition that branches into the loop only if the vector isn't empty.
Related
This question already has answers here:
How do unsigned integers work
(3 answers)
Closed 2 years ago.
I am trying to run a loop on vector but not on the last two elements. So for that I used the following implementation:
vector<int> x;
for(int i=0;i<x.size()-2;i++){
cout<<"looping over element"<<endl;
}
However, running the above code with no elements inserted into x leads to an infinite loop.
Ideone link:
Why do I get this behavior? If x.size()==0 then i<-2 condition should not hold and the code should never enter the for loop
x.size() returns an unsigned value. If this is smaller than 2 then the value will underflow and the result will become very large.
On the other hand since i is a signed type hen it will sooner or later come to the max value of an int (which will still be less than the result of x.size() - 2), and then i++ will lead to arithmetic overflow which is undefined behavior.
Before you attempt this loop you must make sure that x.size() >= 2, and you need to make sure that the counter variable is an unsigned type (like size_t):
if (x.size() >= 2)
{
for (size_t i = 0; i < x.size() - 2; ++i)
{
// ...
}
}
When x.size() is smaller than 2, and you subtract two, you get some big value, as the result is unsigned, and ((someunsigned)-1) is a huge number
So the loop runs:
i=0
i=50000
i=1000000
i=4,294,967,295 //Stop
So, you have no infinite loop, only a very long running loop
This question already has answers here:
Undefined behavior and sequence points
(5 answers)
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 3 years ago.
I have two arrays in my code each one of them have 7 elements, I used a for loop:
for (int i = 0; i < 7; i++)
{
distance = x[++i] - x[i];
area = trapezoidArea(distance, y[++i],y[i]);
sum += area;
}
I wanted to calculate the area of a trapezoid. The difference of x[1]-x[0] will give me the height and y[1] is the first side, and y[0] is the second side.
This for loop doesn't work, and I want to know why.
You can't use ++ as post or pre-increment operator in this case.
This will change the value of your i variable, and therefore your for loop won't have the behaviour you want.
The proper way would be :
for (int i = 0; i < 6; i++)
{
distance = x[i+1] - x[i];
area = trapezoidArea(distance, y[i+1],y[i]);
sum += area;
}
Be careful you have to loop until i<6 because if you let 7, you'll try to access x[7+1] = x[8], and you'll have undefined behaviour or segmentation fault.
++i increases i. So you increase i thrice in one run through the loop, and on top of that, it might also be undefined behavior because of sequencing. What's the i in x[i] supposed to be? The i before the ++i in x[++i] increased it, or after it was increased?
If you want one more than i without increasing it, do i+1 instead. Replacing x[++i] with x[i+1] and likewise with y[++i] should fix this issue. But without seeing all of your code, it's impossible to say if that's the only issue.
When you do ++i in the square brackets, you actually increment the value of i by one. What you should do is i + 1 and leave ++i only in the loop declaration.
This question already has answers here:
Which ordering of nested loops for iterating over a 2D array is more efficient [duplicate]
(10 answers)
Closed 6 years ago.
Which version is more efficient and why?
It seems that both make the same computations. The only thing I can think of is if the compiler recognizes that in (a) j does not change value and doesn't have to compute it over and over again.
Any input would be great!
#define M /* some mildly large number */
double a[M*M], x[M], c[M];
int i, j;
(a) First version
for (j = 0; j < M; j++)
for (i = 0; i < M; i++)
c[j] += a[i+j*M]*x[i];
(b) Second version
for (i = 0; i < M; i++)
for (j = 0; j < M; j++)
c[j] += a[i+j*M]*x[i];
This is about memory-access patterns rather than computational efficiency. In general (a) is faster because it accesses memory with unit stride, which is much more cache-efficient than (b), which has a stride of M. In the case of (a) each cache line is fully utilised, whereas with (b) it is possible that only one array element will be used from each cache line before it is evicted,
Having said that, some compilers can perform loop reordering optimisations, so in practice you may not see any difference if that happens. As always, you should benchmark/profile your code, rather than just guessing.
This question already has answers here:
How to initialize all elements in an array to the same number in C++ [duplicate]
(16 answers)
Closed 6 years ago.
I want to initialize double 2nd array elements as -1 or 0 easily.
In case of integer, we can write like below
int cache[100][100];
memset(cache, -1, 100*100*sizeof(int));
But In case of double, How can I initialize this 2nd array easily? the best approach that I can handle, but quite ugly, is below
double cache[100][100];
for(int i=0; i<100; i++)
for(int j=0; j<100; j++)
cache[i][j] = -1;
Does anybody know best solution about this?
Initializing elements of an array to 0 is simple.
double cache[100][100] = {};
Initializing them to -1 is not easy. You'll have to have the entire array written out as:
double cache[100][100] = {-1, repeat 10000 times};
You can set them to -1 using:
std::fill(cache[0], cache[0]+100*100, -1);
This for loop always crashes immediately:
for (auto i = v.size() - 1; i >=0; --i);
Obviously I have a whole load of code in the loop, and v is a vector of doubles. I'm trying to iterate over them in reverse order.
What is going on here?
for (auto i = v.size() - 1; i >=0; --i);
Look at vector::size() method - it returns usually unsigned int (on strange platforms it might be other unsigned type)! So your i variable will have unsigned type.
When your loop will come to step i == 0 it will decrement it and i will have value 2^32 - 1 == UNSIGNED_INT_MAX (or other positive value if you work on strange platform - see vector::size_type on your platform to see underlying type). So it will never be less then 0, it will never stop your loop. I guess when it turns so big it crashes becouse it goes out of range, but i don't see whole code to be sure.
See here - look for size_type typedef - it says its unsigned type.
You might want to use reverse iterators (see #NathanOliver's response), though i'm not very fond of them in simple loops.
Since i is unsigned it will never be less than 0. It will wrap around to the maximum value that it can hold instead.
If you want to iterate through a vector backwards then you should use a reverse_iterator
std::vector<int> foo = {1,2,3,4,5,6,7,8,9};
for (auto it = foo.rbegin(); it != foo.rend(); ++it)
std::cout << *it << " ";
This will output
9 8 7 6 5 4 3 2 1
The variable i will be an unsigned type.
That can never be less than zero.
Eventually you will access an element outside the vector as i will wrap around to the largest possible unsigned value rather than going negative
What Bathsheba said: the auto type is an unsigned. So decrementing 0 becomes some large positive number, which is >= 0 so the loop continues, but that value is outside the vector's range and causes the crash.