Access the element out of size in C++ vector - c++

Today I try something like this in VS2012 and Max OS 10.7
vector<int> vec;
vector<int> vec2;
for(int i = 0;i < 100 ;i++){
vec.push_back(i);
}
cout << "size: " << vec.size() << endl;
cout << "capacity: " << vec.capacity() << endl;
cout << vec[127] << endl;
//vec2.reserve(10);
fill_n(vec.begin(),128,-1);
cout << vec[127] << endl;
return 0;
as we know the size of vector is the real number of elements in the container, the code above can cause runtime error in VS2012, but it works fine on Max OS, and I try it in Ideone.com and also run successfully, I am not sure if something wrong with the definition of size and capacity, why I can access element out of size?
PS: the capacity at this situation on my computer is 141 on VS2012 and 128 on Mac OS and Ideone.com

std::vector operator [] won't throw any out of range error. It's a undefined behaviour to access element greater than the vector size using [] operator.
Use std::vector::at instead, which throws std::out_of_range

Bump into this problem, I try to elaborate the answer from #P0W.
#1 Access element(s) of the 2d vector
If someone wants to access the elements of the 2d vector,
one should do the following and aware of the API 2dvector.at(row#).at(col#)
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector <vector<int> > vi;
vi.push_back( vector <int>() ); // add empty 1d vector
vi.at(0).push_back( 1 ); // push 1st element
cout << vi.at(0).at(0) << endl; // access element of 2d vector and prints 1
vi.at(0).at(0) = 2; // change number
cout << vi.at(0).at(0) << endl; // access element of 2d vector and prints 2
}
#2 std::out_of_range
if you have difficulty finding the example of std::out_of_range, here is one
example code
// out_of_range example
#include <iostream> // std::cerr
#include <stdexcept> // std::out_of_range
#include <vector> // std::vector
int main (void) {
std::vector<int> myvector(10);
try {
myvector.at(20)=100; // vector::at throws an out-of-range
}
catch (const std::out_of_range& oor) {
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
return 0;
}
output
Out of Range error: vector::_M_range_check

Related

accessing elements of dynamic array of lists

So, I don't know how can I print elements of such a list.
list<int>* a;
a = new list<int>(4);
a[0].push_back(1);
a[0].push_back(3);
a[2].push_back(5);
a[2].push_back(7);
cout << a[0].front() << '\n';
cout << a[1].back() << '\n';
Firstly, I tried to print it via range-based for loop, but it didn't work either.
for(auto element: a[0]) cout << element << '\n'; // doesn't work
Are you trying to store a list of integer lists? Because this implementation will not work since you only have a list of integers and no push_back() operation is available for the elements.
Remove the index operator for all those push_back() operations and take out the index operator for the front() and back() as those are not available to the elements either.
I would use a std::vector instead of new (which should technically be new[] in this case anyway).
#include <iostream>
#include <list>
#include <vector>
int main() {
std::vector<std::list<int>> a(4);
a[0].push_back(1);
a[0].push_back(3);
a[2].push_back(5);
a[2].push_back(7);
for (std::list<int> const& l : a) {
for (int i : l) {
std::cout << i << ' ';
}
std::cout << '\n';
}
}
Output
1 3
5 7

What is the behaviour of vector<T>().swap(x)?

I'm currently trying to re-implement the vector container. I just read on this website that vector<T>().swap(x);, where x is a vector previously declared, could be used to clear and reallocate the x vector to 0.
I realized with this example that I'm not familiar with the use of a constructor (or what I think is a constructor).
#include <iostream>
#include <string>
#include <vector>
typedef std::string T;
void display(const std::vector<T>& input) {
std::cout << "------START------" << std::endl;
for (int i = 0; i < input.size(); i++)
std::cout << input[i] << std::endl;
std::cout << "------END-------" << std::endl;
std::cout << "input size: " << input.size() << std::endl;
std::cout << "input capacity: " <<input.capacity() << std::endl;
}
int main() {
std::vector<T> src(1, "Matthieu0");
std::vector<T> empty;
src.push_back("Guillaume1");
src.push_back("Paul2");
src.push_back("Julien3");
std::vector<T> tmp(src);
std::cout << "------swap1------" << std::endl;
display(empty);
empty.swap(tmp);
display(empty);
std::cout << "------swap2------" << std::endl;
display(src);
std::vector<T>().swap(src);
display(src);
return 0;
}
So, I have no problem understanding swap1 behavior, crystal clear. But I don't understand what is happening under the hood with swap2 and how I could implement it.
But I don't understand what is happening under the hood with swap2
When you wrote
//-vvvvvvvvvvvvvvvv------------->a temporary std::vector
std::vector<T>().swap(src); //this calls swap on the temporary(unnamed) std::vector
In the above statement you're calling std::vector::swap on the temporary(unnamed) std::vector created from the expression std::vector<T>().
This is similar to the swap1 that you did with the exception that in swap1 you were calling std::vector::swap on a named object empty but here you're calling it on the temporary object.
Many developers want to release memory occupied by a vector after std::vector::resize(0).
It can be done since C++11 by calling std::vector::shrink_to_fit(). There is no such method until C++11, in C++98, and developers use such a trick:
Create an empty vector.
Swap contents of vectors.
Destroy the vector created on the step 1.
For performing the step 3 as much earlier as possible, the limited scope block { ... } is used.
std::vector<int> v(10);
std::cout << v.size(); << std::end; // prints 10
{
std::vector<int> tmp;
std::cout << tmp.size(); << std::end; // prints 0
v.swap(tmp);
std::cout << tmp.size(); << std::end; // prints 10
}
std::cout << v.size(); << std::end; // prints 0
It can be shorter if an unnamed temporary vector generated by a compiler is used. The life time of an unnamed temporary variable is well known:
std::vector<int> v(10);
std::cout << v.size(); << std::end; // prints 10
v.swap(std::vector<int>());
std::cout << v.size(); << std::end; // prints 0
std::vector<int> v(10);
std::cout << v.size(); << std::end; // prints 10
std::vector<int>().swap(v);
std::cout << v.size(); << std::end; // prints 0
It can be still used since C++11 for making
v.resize(0);
v.shrink_to_fit();
shorter and to guarantee freeing memory:
v.swap({});

Visual Studio does not show in which line error is

When I am programming in C++ and Visual Studio 2019 throws an error, it shows in which line it was encountered. But when coding with C++ when error is thrown, it does not show in which line exactly it appears. So it makes hard to debug and fix my program. Maybe there are settings that I need to adjust?
C++ error (it point to some 1501 line of installation files that weren't created by me):
vector<int> myVector(2);
cout << myVector[4] << endl;
Errors in both programs in these examples are of a same category: vector (in C++).
Without providing more code and looking at the minimal c++ code you provided:
vector<int> myVector(2);
cout << myVector[4] << endl;
It looks like you have too many elements in myVector in the second line. You will have UB because the [] operator does not allocated more elements. You only declared 2 elements.
Now, when you send your vector to cout you are saying you have 4 which is false.
That is why you are getting the error: "Expression: vector subscript out of range".
You only have two indices 0 and 1, if you define a vector with 2 elements.
Now if you were trying to see the size of your vector you use the .size() function which returns the number of elements in the vector.
vector<int> myVector(2);
cout << myVector.size() << endl;
You could even do something like this with a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> myVector(2);
std::cout << myVector.size() << std::endl;
for (int i = 0; i < 10; i++)
myVector.push_back(i);
std::cout << myVector.size() << '\n';
return 0;
}

std::vector<int> allocated with (n,0) is not iterable

Consider the following code:
#include <vector>
#include <iostream>
void monitor_vector(std::vector<int> myV)
{
std::vector<int>::iterator it = myV.begin();
std::cout << "Vector size: " << myV.size() << std::endl;
while (*it)
{
std::cout << "Element " << it-myV.begin() << ": " << *it << std::endl;
it++;
}
}
int main()
{
std::vector<int> myVector(4,1);
monitor_vector(myVector);
return 0;
}
Basically, I create a std::vector<int> that has 4 elements, and assign each element 1. When I execute this code, all is well. The output shows each element.
However, when I execute it with this line
std::vector<int> myVector(4,1);
replaced by this line:
std::vector<int> myVector(4,0);
I can't see any output. The output is:
yilmazali#yilmazali:~/cpp_practice$ g++ -o la vector_practice.cpp
yilmazali#yilmazali:~/cpp_practice$ ./la
Vector size: 4
yilmazali#yilmazali:~/cpp_practice$
Why does it ignore the elements with default integer value? Still, they are there as the member of std::vector.
Thanks for your time,
Ali
You iterate while (*it).
If you fill your vector with zeros, *it == 0 and therefore if (*it) is like if (false): the loop body is never executed.
Instead, loop while it != myV.end()

std vector does not throw out_of_range exception when accessing uninitialized elements [duplicate]

This question already has answers here:
Vector going out of bounds without giving error
(4 answers)
Closed 5 years ago.
I read this tutorial
std::vector beginners tutorial
and also saw this question:
similar tpoic question
Yet, when I run my simple example I did not see the excepted results, which are --> an std::out_of_range exception is NOT thrown.
Did I misunderstand here something ?
The sample code I run is the following (the code run and terminates successfully, i.e.- no exceptions thrown):
#include <iostream>
#include <vector>
using namespace std;
class MyObjNoDefualtCtor
{
public:
MyObjNoDefualtCtor(int a) : m_a(a)
{
cout << "MyObjNoDefualtCtor::MyObjNoDefualtCtor - setting m_a to:" << m_a << endl;
}
MyObjNoDefualtCtor(const MyObjNoDefualtCtor& other) : m_a(other.m_a)
{
cout << "MyObjNoDefualtCtor::copy_ctor - setting m_a to:" << m_a << endl;
}
~MyObjNoDefualtCtor()
{
cout << "MyObjNoDefualtCtor::~MyObjNoDefualtCtor - address is" << this << endl;
}
// just to be sure - explicitly disable the defualt ctor
MyObjNoDefualtCtor() = delete;
int m_a;
};
int main(int argc, char** argv)
{
// create a vector and reserve 10 int's for it
// NOTE: no insertion (of any type) has been made into the vector.
vector<int> vec1;
vec1.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
size_t index = 0;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would excpet here an excpetion to be thrown.
index = 9;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// same thing goes for user defined type (MyObjNoDefualtCtor) as well
vector<MyObjNoDefualtCtor> vec2;
vec2.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 0;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 9;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
return 0;
}
Notes:
The sample code is compiled with -std=c++11 option.
Compiler version is g++ 5.4 (on my Ubuntu 16.04 machine).
Thanks,
Guy.
A vectors operator[] function may or may not do bounds-checking. The implementations that do have bounds-checking, typically only does it for debug-builds. GCC and its standard library doesn't.
The at function on the other hand, does have mandatory bounds-checking and will be guaranteed to throw an out_of_range exception.
What happens here is simply that you go out of bounds and have undefined behavior.
Is at() that perform the range check, not (necessarily) operator[].
Your code have udefinded behaviour.
If you want to be sure to get an exception, use
vec1.at(index)
instead of
vec1[index]