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
Removing Leading and Trailing Spaces from a String
Heterogeneous Containers in C++
Vector Size - 1 When Size Is 0 in C++
How to Get Std::Vector Pointer to the Raw Data
Conversion of 2D Array to Pointer-To-Pointer
Fast Ceiling of an Integer Division in C/C++
Implicit Type Conversion With Template
Access Friend Function Defined in Class
How to Initialise Memory With New Operator in C++
C/C++ Int[] VS Int* (Pointers Vs. Array Notation). What Is the Difference
Efficient String Concatenation in C++
What Does Opencv'S Cvwaitkey( ) Function Do
Should the Exception Thrown by Boost::Asio::Io_Service::Run() Be Caught
Checking If a Directory Exists in Unix (System Call)
Arrays VS Vectors: Introductory Similarities and Differences