Reputation: 627
Have a doubt in using vectors in C++. it is to do with the push_back method in the vector. For the first program, i have used push_back to insert elements into the vector. For the second program, i have used at( ) to insert elements into the vector.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main ()
{
std::vector<string> myvector (3);
cout << "In main" << endl;
for (unsigned i=0; i<myvector.size(); i++)
{
myvector.push_back("hi"); //Note: using push_back here.
}
cout << "elements inserted into myvector" << endl;
std::cout << "myvector contains:" << endl;
for (auto v: myvector)
cout << v << endl;
// access 2nd element
cout << "second element is " << myvector[1] << endl;
return 0;
}
Output:
Hangs after entering main.
$ ./a.out
In main
whereas if I used myvector.at() to insert the elements like below, its fine.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main ()
{
std::vector<string> myvector (3);
cout << "In main" << endl;
for (unsigned i=0; i<myvector.size(); i++)
{
myvector.at(i) = "hi"; // using 'at' instead of 'push_back'
}
cout << "elements inserted into myvector" << endl;
std::cout << "myvector contains:" << endl;
for (auto v: myvector)
cout << v << endl;
// access 2nd element
cout << "second element is " << myvector[1] << endl;
return 0;
}
Output:
./a.out
In main
elements inserted into myvector
myvector contains:
hi
hi
hi
second element is hi
$
What is wrong with the way i have used push_back ? This is one of the ways we insert elements into the vector, right.
Upvotes: 1
Views: 3789
Reputation: 2355
push_back
adds a new element at the end of a vector
. It increases the size and does not provide access to existing elements.
at()
is to access an element of a vector
. It does not increase the size of vector
and does not add an element to it. it is to read/write of an existing element.
So we can not compare these two with each other. Each does a different job.
We can however compare operator[]
with at()
. The former does not throw out a range exception, cause it does not check, while the latter check out of bound and throws an exception when it should.
Other answers fully covered why the first code hangs so I am not repeating them here.
Upvotes: 1
Reputation: 122476
The problem is that you push the elements in a loop that never stops:
for (unsigned i=0; i<myvector.size(); i++)
{
myvector.push_back("hi"); //Note: using push_back here.
}
After the first iteration the vector will have 4
elements and i
will be 1
. As you increment i
by one in each iteration and myvector.size()
also increases by one, the condition will never be false.
std::vector::at
on the other hand, does not add elements to the vector. Hence, after 3 iterations the loop ends.
Upvotes: 5
Reputation: 2188
The problem is in this line:
std::vector<string> myvector (3);
You are declaring a vector with 3 elements. In this case, those elements are empty strings.
When you later do myvector.pushback("hi")
You add elements to your vector. The previous empty string are still there in in front of your added string.
To define an empty vector, you just do:
std::vector<string> myvector;
and if you know you are going to add 3 elements you can also do
std::vector<string> myvector;
myvector.reserve(3);
The purpose of reserve
is to preallocate memory. This preallocated memory will not be part of your vector until you actually insert any new elements.
Remember that std::vector
is not supposed to behave like c
-like arrays. The purpose of std::vector
is to be resizable, so you don't need to decide up front how many elements you need, or keep track of its current used size.
Upvotes: 2
Reputation: 60238
The issue in this loop:
for (unsigned i=0; i<myvector.size(); i++)
{
myvector.push_back("hi"); //Note: using push_back here.
}
is that if you ever enter the loop, i.e. myvector
is not initially empty, then each push_back
will increase the size of the vector. Since i
is incremented once each time in the loop, it will never catch up to the size of the vector, and you end up with an infinite loop.
.at()
doesn't have this problem, since it only indexes into the vector, without ever changing its size. So long as the argument to at
is a valid index, you can access this position without any issues.
Upvotes: 8