Why I can't input into my std::vector in C++ - c++

I'm a newbie in C++. I've just learnt about vector in STL.
However, when I tried to input an integer into my vector:
vector<int> v;
cin>>v[i]
The program returned segmentation fault. Please help me out.

Your vector doesn't have any elements in it, so the internal array is null. When you try to read something into it, you're trying to deference a null pointer (resulting in the segfault). Add elements to the vector first:
vector<int> v(100); //Create vector with 100 elements
for(int i = 0; i < 100; i++) {
cin >> v[i];
}
Alternatively, you could read elements into a local variable, then add them into the vector:
vector<int> v;
for(int i = 0; i < 100; i++) {
int new_val;
cin >> new_val;
v.push_back(new_val);
}

Related

What's the difference between vector<vector<int>> vec and vector<vector<int>> vec(n)? [duplicate]

This question already has answers here:
Why does my vector print out all zeroes?
(4 answers)
Closed 1 year ago.
I was trying to access vector elements today, so when I used vector<vector<int>> vec and then added elements to it. I was able to access those elements like vec[1][2].
But when I use vector<vector<int>> vec(n) and then added elements, I was not able to access the elements using vec[1][2]. I keep getting a segmentation error. Does anyone know what am I missing here?
I am adding the elements to the vector through with the help of the below code snippet.
int n;
cin >> n;
vector<vector<int>> vh;
int size, input;
for (int i = 0; i < n; i++)
{
vector<int> temp;
cin >> size;
for (int j = 0; j < size; j++)
{
cin >> input;
temp.push_back(input);
}
vh.push_back(temp);
}
I think I can guess what the problems is...
When you use the constructor with an argument:
vector<vector<int>> vh(n);
you create a vector with the size n, it means it will already have n elements, where each element will be a default-constructed vector<int>. Which means that each vector will be empty.
Then you push back a new vector:
vh.push_back(temp);
This will increase the size of the vector. After one such push_back call the size of vh will be n + 1. The new vector you add will be at index n, i.e. vh[n] is the new vector.
If you set the size when you define the vector, then you need to use indexing and assignment to set the sub-vectors:
vh[i] = temp;
To summarize:
Either you create an empty vector and push back new elements:
vector<vector<int>> vh;
and
vh.push_back(temp);
Or you create a vector with a size, and use indexing and assignment:
vector<vector<int>> vh(n);
and
v[i] = temp;
Don't mix these ways.
Now when you got your current code working (hopefully) and understand how these things work a little better, it's time to show a way how to do your code in a more "C++-ish" way... :)
// The first part is much like your current code
size_t n;
std::cin >> n;
std::vector<std::vector<int>> vh(n);
// Now iterate over all the elements in the vector
for (auto& v : vh)
{
// Get the size of the current sub-vector
size_t size;
std::cin >> size;
// Create the vector with size elements
v = std::vector<int>(size);
// Read size integers into the vector
std::copy_n(std::istream_iterator<int>(std::cin), size, begin(v));
}

Problem with understanding a vector initialization

This might be a dumb question but there is something I can't quite understand. When using a vector, whenever I want to 'push_back' an element to a certain position I can do that only if I initialize the vector in a certain way.
For example when I use this initialization:
std::vector<int> Myvec;
int size = 0;
int x = 0;
std::cin >> size;
for(int i = 0; i < size; i++)
{
std::cin >> x;
Myvec[i].push_back(x);
}
I receive the following error:
request for member 'push_back' in 'Myvec.std::vector<_Tp, _Alloc>::operator[] >(((std::vector::size_type)i))', which is of non-class type '__gnu_cxx::__alloc_traits >::value_type {aka int}'|
But when I use the following initialization it works:
int size = 0;
int x = 0;
std::cin >> size;
std::vector<int> Myvec[size];
for(int i = 0; i < size; i++)
{
std::cin >> x;
Myvec[i].push_back(x);
}
I don't have any problem using it and can implement it in all sorts of tasks, but it's bugging me because I'm not sure why it is actually working. Thank you for your help in advance.
In the first block you should use:
std::vector<int> Myvec;
int size = 0;
int x = 0;
std::cin >> size;
for(int i = 0; i < size; i++)
{
std::cin >> x;
Myvec.push_back(x);
}
Or you can use:
int size = 0;
int x = 0;
std::cin >> size;
std::vector<int> Myvec(size);
for(int i = 0; i < size; i++)
{
cin>>Myvec[i];
}
And print the vector using:
for(int i = 0; i < size; i++) {
std::cout<< Myvec[i]<<" ";
}
When you initialise it using vector Myvec[size], it becomes vector of vectors with size "size", means each Myvec[i] is a vector in which you can push elements.
Read more here: https://www.geeksforgeeks.org/2d-vector-in-cpp-with-user-defined-size/
You have a misunderstanding on how the std::vector::push_back function works. It basically appends a new object at the end of the vector. In particular, you don't need to index into the vector with std::vector::operator[]. Instead, change your snippet to
for(int i = 0; i < size; i++)
{
std::cin >> x;
Myvec.push_back(x);
}
The solution you came up with does something that you probably don't intend, i.e., using a raw array of vectors: when transferring user input into the objects, it creates size vectors with one element each.
You're not putting an element at position i in a vector.
You're putting an element at the back of the ith vector in an array of vectors! Worse, the array is empty, so the access is invalid.
If it weren't, though, you'd end up with i vectors each having one element. Not good!
Instead, you can make your vector be of a certain size:
MyVec.resize(SomeSize);
…then assign the elements as if the vector were an array (which it kind of is):
MyVec[i] = thing;
The key point here is that you don't have to push_back; you only do that when you want to push a new element to the back of the vector. You can access existing values with array-like [] syntax just fine.
Read more about vectors in your C++ book.

insert value in dynamic array with loop using vector in c++

I want to insert value in dynamic array k. this is my code.
cin >> n;
std::vector<int> k;
for(int i = 0 ; i< n ; i++) {
cin >> k[i];
}
But it is not storing any value. I don't know why, please help me
Because vector is dynamic array, you should specify that you want to add a new element by using push_back instead of operator [].
Following piece of code would work:
for(int i = 0 ; i< n ; i++) {
int element;
cin >> element;
k.push_back(element);
}
Or even better you can initialise your vector object by calling the constructor which takes initial container size as an parameter. Later you always can add new elements to the vector again by using push_back.
cin >> k[i]; is trying to read into a location of the vector that does not exist yet (k is an empty container with zero elements).
You want to first read in the integer and then add it to the vector like so:
int num;
cin >> num;
k.push_back(num);
Alternatively you could resize k first, so it has elements at all indices you are going to access, by doing k.resize(n); after reading in n (or just create it with the right size right away) and then your existing code will be fine.
std::vector::operator[] does not resize the container. It only accesses pre-existing elements and if the accessed element is not within bounds of the container the behaviour is undefined.
You will need to use push_back in this case should be something like this:
#include <vector>
int main ()
{
std::vector<int> myvector;
int myint;
std::cout << "Please enter some Numbers (enter 0 to end):\n";
do {
std::cin >> myint;
myvector.push_back (myint);
} while (myint);
std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";
return 0;
}
This is a sample code but should give you the idea on how to get around with Vectors and push_back.
cheers
you don't need to take another variable just write
vector<int>k
for(int i = 0 ; i< n ; i++) {
k.push_back(i);
}

How to free dynamically allocated vector?

I tried to create vector of vector int, and I confused how do i free the dynamically allocated vector after.
The following is my code:
vector<int> *j;
vector< vector<int> > i; //vector of vector<int>
int c; //offset of the number
cin.ignore();
for(int count = 0; count < cas; count++ )
{
c = 0;
char line[1000];
j = new vector<int>;
cin.getline(line, 1000);
//tokenize the input string which separate by space “ ”
char *p = strtok(line, " ");
while(p != NULL)
{
n[c] = string(p);
c++;
p = strtok(NULL, " ");
}
//convert the string input to integer for further calculation
for(int m = 0; m < c; m++)
{
(*j).push_back(atoi(n[m].c_str()));
}
i.push_back(*j);
}
//this is the way i try to free the allocated vector, and i get segmentation fault for this
j = &i[0];
delete [] j;
You don't need any pointers or new or delete. These are advanced concepts that have no place in this simple program.
vector<vector<int>> i;
for (...) {
vector<int> j;
// fill up j
i.push_back(j);
}
Remember, a vector of vectors is not conceptually different from a vector of ints. You don't start new'ing and delete'ing ints when you need to fill up a vector<int>. Nor do you need to do so for any X when you work with a vector<X>.
The
i.push_back(*j);
does't push the pointer; it makes a copy of the vector.
As soon as you've done that, you can
delete j;
there and then.
(Of course if you change i to store pointers, the story will be completely different.)

Program declaring variables by itself

I am still a ... novice, in c++.
I don't know the name of what I am looking for but
I 've been searching a lot but can't seem to find the answer to following question:
I want to write a program that would declare demanded number of variables.
Example:
int a;
cin>>a;
Now if "a" is 5 (or any other number), I want program to declare 5 more variables,
Names do not matter but let's say...n1,n2,n3,n4,n5.
I've tried array and for loop but can't get it to work.
I got answer on Croatian forum (forum.hr) but the forum is currently offline, so I had no
time to try it out...
It was about using heap instead of stack
Thx in advance
C++ has container classes for this purpose. In particular, you want a vector:
std::vector<int> a(size);
for (int i = 0; i < a.size(); ++i)
std::cin >> a[i];
Declares a vector a of integers of some size and reads its elements, one by one.
If this is C++, the best you can do is using std::vector as it will manage the memory for you.
you can store them in an array:
int a;
cin >> a;
int *number = new int[a]; // allocate an array of size a
for (int i = 0; i < a; i++) {
number[i] = 5 + i; // set your numbers to anything here
}
delete[] number; // otherwise you have memory leak
or better use a vector:
vector<int> number(a);
// iterate with a normal for loop
for (int i = 0; i < number.size(); i++) {
number[i] = 5 + i;
}
..
// or use iterators
for (vector<int>::iterator it = number.begin(); it != number.end(); ++it) {
cout << *it << endl;
}
so you don't have to manage memory.