Vector Size - 1 When Size Is 0 in C++

why is ( 0 v.size()-1 ) when the vector v is empty?

v.size() has an unsigned return type. Subtracting 1 from an unsigned 0 results in wrap around to some "very large" unsigned number (this is modulo arithmetic).

0 will be less than some "very large" number, always.

It's a common gotcha when working with standard containers and mixing signed/unsigned indices/sizes.

vector size - 1 when size is 0 in C++

vector::size() is of type size_t which is an unsigned type, and unsigned integers can't represent negative numbers.

c++ vector size. why -1 is greater than zero

Because the size of a vector is an unsigned integral type. You are comparing an unsigned type with a signed one, and the two's complement negative signed integer is being promoted to unsigned. That corresponds to a large unsigned value.

This code sample shows the same behaviour that you are seeing:

#include <iostream>
int main()
{
std::cout << std::boolalpha;
unsigned int a = 0;
int b = -1;
std::cout << (b < a) << "\n";
}

output:

false

vector.size() returns 0 all the time

Your constructor makes a local variable that shadows your member variable

MyVector::MyVector(int num) {
vector<int> some_vector(num);
}

Instead use the member initialization list

MyVector::MyVector(int num)
: some_vector(num)
{
}

why is ( 0 v.size()-1 ) when the vector v is empty?

v.size() has an unsigned return type. Subtracting 1 from an unsigned 0 results in wrap around to some "very large" unsigned number (this is modulo arithmetic).

0 will be less than some "very large" number, always.

It's a common gotcha when working with standard containers and mixing signed/unsigned indices/sizes.

Loop is not terminating, please someone explain what am doing wrong

vec.size() returns an unsigned type, so size() - 1 will wrap around to a very large value if size() is 0. You don't need the - 1 in the first place, since your inner loop already handles the edge cases where pairs of integers are not available to multiply.

You also don't need the overhead of vec.at(index) since your loops are doing adequate bounds checking on their own, so you can use vec[index] instead.

Try this:

std::vector<int> vec{};
int result{0};

for (size_t i = 0; i < vec.size(); ++i) {
for (size_t j = i + 1; j < vec.size(); ++j) {
result += vec[i] * vec[j];
}
}
std::cout << result;

Online Demo

Logic behind v.size()-1?

the book said the last element in the vector is v[v.size()-1]

That's true, but only when v.size() > 0. If the vector is empty, its size is 0, but the value returned by std::vector::size() is of type std::vector::size_type which is an unsigned integer type (usually std::size_t), so that the result "wraps around" becoming an "unexpected" huge value (the maximum representable value of size_type, actually).

You can also use v.back(), where std::vector::back() "returns reference to the last element in the container. Calling back on an empty container causes undefined behavior."

What is the logic behind this?

In C++, vector (and array) indeces start from 0, so that v[0] would return a reference to the first element, if present. In general accessing a nonexistent element through operator[] is undefined behavior.

To picture it, let's consider a vector of size 5.


v[0] v[1] v[2] v[3] v[4]
+-----+-----+-----+-----+-----+ - -
| 1 | 2 | 3 | 4 | 5 | |
+-----+-----+-----+-----+-----+ - -
^ ^
v.begin() v.end()

Note that the v.end() iterator points exactly at v.begin() + v.size() and that the last accessible element is the one before that.

vector.size() is working unexpectedly in comparision

The problem is your loop:

 for(int i = 0; i < v.size() -1;++i)

More specifically, this part of the condition: v.size() - 1.

The size function returns a value of type size_type, which if you read e.g. this vector reference will see is an unsigned type.

That means when you subtract 1 from the value 0, you don't get -1 but instead get a very large value since unsigned underflow wraps around to its highest value.

That means your loop will indeed iterate, at least once, and lead to UB (Undefined Behavior) when you index out of bounds.



Related Topics



Leave a reply



Submit