C++ vector: std::out_of_range Error - c++

I have a structure in which I have a vector
vector<int> accept;
In my program , when I try to insert a value at a specific index. I get this error:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check
In each iteration of my loop, I increment the AlphabetCounter and place a value at that specific index like the code given below :
AlphabetCounter=AlphabetCounter+1;
NewNextStateDouble.accept.at(AlphabetCounter)=1;
AlphabetCounter=-1 before starting the loop.
I don't get it why out of range error is occuring.

You can only grow a vector by using these two methods below:
Using the resize() method:
std::vector<int> my_vector;
v1.resize( 5 );
Using the push_back() method for dynamically increasing the size of the vector:
std::vector<int> my_vector;
for( int i = 0; i != 10; ++i )
{
my_vector.push_back( i );
}
std::cout << "The vector size is: " << my_vector.size() << std::endl;
In your situation, you have to know that subscripting does not add elements, as the standard says:
The subscript operator on vector (and string) fetches an existing
element; it does not add an element.
Also some recommendations about subscripting can be seen below.
Subscript Only Elements that are Known to Exist!
It is crucially important to understand that we may use the subscript operator
(the [] operator) to fetch only elements that actually exist. ( For example, see the code below )
It is an error to subscript an element that doesn’t exist, but it is an error that
the compiler is unlikely to detect. Instead, the value we get at run time is
undefined. (usually, an out_of_range exception)
Attempting to subscript elements that do not exist is, unfortunately, an
extremely common and pernicious programming error. So-called buffer
overflow errors are the result of subscripting elements that don’t exist. Such
bugs are the most common cause of security problems in PC and other
applications.
vector<int> ivec; // empty vector
cout << ivec[0]; // error: ivec has no elements!
vector<int> ivec2(10); // vector with ten elements
cout << ivec2[10]; // error: ivec2 has elements 0 . . . 9

You vector must have at least AlphabetCounter + 1 elements when you want to change a value at the position AlphabetCounter. You must make sure that is the case before you access the value.

std::vector does not grow to a specific index if the vector does not have enough elements. If you know the size (you need that to insert at a specific index) then you should resize() the vector to the appropriate size.

you have created an empty vector....use accept.push_back(5) ....
Description of push_back() method
Adds a new element at the end of the vector, after its current last element.
The content of val is copied (or moved) to the new element.
This effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size
surpasses the current vector capacity.

Related

Getting error while inputting value at 2d vector

I am using Codeblock to write c++ code. I was trying to input value at 2d vector. But it is getting an error. I am new at c++ and I have already searched at google but haven't found any solution. This is my code
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector <vector<double>> customar_data;
double value;
cin >> value;
customar_data[0][0].push_back(value);
cout >> customar_data[0][0];
return 0;
}
This is what codeblocks compiler showing
For the compiler's error, look at the types of the expressions involved.
customar_data is a vector <vector <double>>
customar_data[0] is a <vector <double>>
customar_data[0][0] is a double
The compiler complains when you request a member function (push_back) of the non-class type double.
For the logical error, look at what you are requesting. You start by constructing an empty vector (of vector<double>). Then you try to access the first element of this empty vector. You can avoid the need to specify the vector's size during construction, or you can access elements without adding them to the constructed vector, but you cannot do both. Vectors do not automatically increase in size as a result of accessing elements that had not existed.
The valid indices/subscripts to access are the non-negative integers less than the vector's size(). A default constructed vector starts with a size of zero, so there are no valid indices (you would need a non-negative integer less than zero). If you know how big you want the outermost vector to be when you construct it, you may want to specify that.
vector <vector<double>> customar_data(10);
// At this point, customar_data[0] through customar_data[9] can be used.
// Each of these elements is an empty vector of doubles.
If you do not know how big the outermost vector is going to be, you'll need to add each element before you use it. (This is intentionally singular; you can add an element, use it, then add another.)
vector <vector<double>> customar_data;
customar_data.push_back(vector<double>()); // Adds an empty vector as the first element.
customar_data[0].push_back(20.0); // Adds a value to the vector that is the first element.
// At this point, customar_data[0][0] is valid and has the value 20.0.
You might find that the emplace_back member function is more convenient than push_back, but let's go one step at a time.

how does random access of an element in deque gives constant time complexity? [duplicate]

This question already has answers here:
STL deque accessing by index is O(1)?
(4 answers)
Closed 4 years ago.
Deque gives constant complexity for accessing any element( cpp reference ). In Vector, it's always constant complexity(the address of the first element in vector + no of elements * size of each element) but how does it work for Deque? Deque elements are not contiguous in memory, so how does it enable O(1) time complexity to access any element? When I ran the following program, in the case of Vector, it gives correct output, but for Deque, it gives some arbitrary numbers (agreed to not give the correct result because elements are not contiguous).
vector<int> v1;
deque<int> d1;
for(int i =0; i < 1000000;++i)
v1.push_back(i);
for( int j =0; j < 1000000;++j)
d1.push_back(j);
cout << *(&v1[0] +90000) << endl; // output 90000
cout << *(&d1[0] +90000)<<endl; // Output is not 90000
A deque is typically implemented as a two-layer structure, the top level is an array of pointers to fixed-sized chunks. Using knowledge of that size it is constant complexity to determine which chunk holds the item of interest and constant complexity to determine which item in the chunk is being requested.
Just because it is constant does not indicate that it is always a simple direct memory access, only that all accesses for that particular operation will require the same steps.
Don't let the "1" confuse you. O(1) is the computer-science way of saying that the number of calculation steps necessary to arrive at the desired element does not depend on the size of the container. Whether you have a std::deque<T> with 10 elements or a std::deque<T> with 10000000 elements doesn't matter - getting the desired element at index i always involves two pointer dereferences.
See https://en.cppreference.com/w/cpp/container/deque:
typical implementations use a sequence of individually allocated
fixed-size arrays, with additional bookkeeping, which means indexed
access to deque must perform two pointer dereferences
Compare this to a std::list<T>, where the number of calculation steps necessary to get the element at index i does depend on the size of the container.
Random access to deque elements involves two pointer de-referencing, and is constant across any elements. However it won't be as efficient as vector.

exceeding vector does not cause seg fault

I am very puzzled at the result of this bit of code:
std::vector<int> v;
std::cout << (v.end() - v.begin()) << std::endl;
v.reserve(1);
std::cout << (v.end() - v.begin()) << std::endl;
v[9] = 0;
std::cout << (v.end() - v.begin()) << std::endl;
The output:
0
0
0
So... first of all... end() does not point to the end of the internal array but the last occupied cell... ok, that is why the result of the iterator subtraction is still 0 after reserve(1). But, why is it still 0 after one cell has been filled. I expected 1 as the result, because end() should now return the iterator to the second internal array cell.
Furthermore, why on earth am I not getting a seg fault for accessing the tenth cell with v[9] = 0, while the vector is only 1 cell long?
First of all, end() gives you an iterator to one beyond the last element in the vector. And if the vector is empty then begin() can't return anything else than the same as end().
Then when you call reserve() you don't actually create any elements, you only reserve some memory so the vector don't have to reallocate when you do add elements.
Finally, when you do
v[9] = 0;
you are indexing the vector out of bounds which leads to undefined behavior as you write to memory you don't own. UB often leads to crashes, but it doesn't have too, it may seem to work when in reality it doesn't.
As a note on the last part, the [] operator doesn't have bounds-checking, which is why it will accept indexing out of bounds. If you want bounds-checking you should use at().
v[9] = 0;, you're just accessing the vector out of bound, it's UB. It may crash in some cases, and may not. Nothing is guaranteed.
And v[9] = 0;, you don't add element at all. You need to use push_back or resize:
v.push_back(0); // now it has 1 element
v.resize(10); // now it has 10 elements
EDIT
why does v[index] not create an element?
Because std::vector::operator[] just doesn't do that.
Returns a reference to the element at specified location pos. No bounds checking is performed.
Unlike std::map::operator[], this operator never inserts a new element into the container.
So it's supposed that the vector has the sufficient elements for the subscript operator.
BTW: What do you suppose vector should do when you write v[9] = 0? Before set the 10th element to 0, it has to push 10 elements first. And How to set their values? All 0? So, it won't do it, the issue just depends on yourself.
This is a guess, but hopefully a helpful one.
You will only get a segfault when you attempt to access an address that has not been assigned to your process' memory space. When the OS gives memory to a program, it generally does so in 4KB increments. Because of this, you can access past the end of some arrays/vectors without triggering a segfault, but not others.

Filling a vector with out-of-order data in C++

I'd like to fill a vector with a (known at runtime) quantity of data, but the elements arrive in (index, value) pairs rather than in the original order. These indices are guaranteed to be unique (each index from 0 to n-1 appears exactly once) so I'd like to store them as follows:
vector<Foo> myVector;
myVector.reserve(n); //total size of data is known
myVector[i_0] = v_0; //data v_0 goes at index i_0 (not necessarily 0)
...
myVector[i_n_minus_1] = v_n_minus_1;
This seems to work fine for the most part; at the end of the code, all n elements are in their proper places in the vector. However, some of the vector functions don't quite work as intended:
...
cout << myVector.size(); //prints 0, not n!
It's important to me that functions like size() still work--I may want to check for example, if all the elements were actually inserted successfully by checking if size() == n. Am I initializing the vector wrong, and if so, how should I approach this otherwise?
myVector.reserve(n) just tells the vector to allocate enough storage for n elements, so that when you push_back new elements into the vector, the vector won't have to continually reallocate more storage -- it may have to do this more than once, because it doesn't know in advance how many elements you will insert. In other words you're helping out the vector implementation by telling it something it wouldn't otherwise know, and allowing it to be more efficient.
But reserve doesn't actually make the vector be n long. The vector is empty, and in fact statements like myVector[0] = something are illegal, because the vector is of size 0: on my implementation I get an assertion failure, "vector subscript out of range". This is on Visual C++ 2012, but I think that gcc is similar.
To create a vector of the required length simply do
vector<Foo> myVector(n);
and forget about the reserve.
(As noted in the comment you an also call resize to set the vector size, but in your case it's simpler to pass the size as the constructor parameter.)
You need to call myVector.resize(n) to set (change) the size of the vector. calling reserve doesn't actually resize the vector, it just makes it so you can later resize without reallocating memory. Writing past the end of the vector (as you are doing here -- the vector size is still 0 when you write to it) is undefined behavior.

Stumped at a simple segmentation fault. C++

Could somebody be kind to explain why in the world this gives me a segmentation fault error?
#include <vector>
#include <iostream>
using namespace std;
vector <double>freqnote;
int main(){
freqnote[0] = 16.35;
cout << freqnote[0];
return 0;
}
I had other vectors in the code and this is the only vector that seems to be giving me trouble.
I changed it to vector<int>freqnote; and changed the value to 16 and I STILL get the segmentation fault. What is going on?
I have other vector ints and they give me correct results.
Replace
freqnote[0] = 16.35;
with
freqnote.push_back(16.35);
and you'll be fine.
The error is due to that index being out-of-range. At the time of your accessing the first element via [0], the vector likely has a capacity of 0. push_back(), on the other hand, will expand the vector's capacity (if necessary).
You can't initialise an element in a vector like that.
You have to go:
freqnote.push_back(16.35),
then access it as you would an array
You're accessing vector out of bounds. First you need to initialize vector specifying it's size.
int main() {
vector<int> v(10);
v[0] = 10;
}
As has been said, it's an issue about inserting an out of range index in the vector.
A vector is a dynamically sized array, it begins with a size of 0 and you can then extend/shrink it at your heart content.
There are 2 ways of accessing a vector element by index:
vector::operator[](size_t) (Experts only)
vector::at(size_t)
(I dispensed with the const overloads)
Both have the same semantics, however the second is "secured" in the sense that it will perform bounds checking and throw a std::out_of_range exception in case you're off bound.
I would warmly recommend performing ALL accesses using at.
The performance penalty can be shrugged off for most use cases. The operator[] should only be used by experts, after they have profiled the code and this spot proved to be a bottleneck.
Now, for inserting new elements in the vector you have several alternatives:
push_back will append an element
insert will insert the element in front of the element pointed to by the iterator
Depending on the semantics you wish for, both are to be considered. And of course, both will make the vector grow appropriately.
Finally, you can also define the size explicitly:
vector(size_t n, T const& t = T()) is an overload of the constructor which lets you specify the size
resize(size_t n, T const& t = T()) allows you to resize the vector, appending new elements if it gets bigger than it was
Both method allow you to supply an element to be copied (exemplar) and default to copying a default constructed object (0 if T is an int) if you don't supply the exemplar explicitly.
Besides using push_back() to store new elements, you can also call resize() once before you start using the vector to specify the number of elements it contains. This is very similar to allocating an array.