How to access an index in a vector without segfaulting - c++

I know this is simple, so I apologize in advance.
I am segfaulting when trying to access a vector by index. For example...
vector<float> some_vec;
int i = 0;
for (some iterator loop here)
{
//snip
some_vec[i] = some_float;
i++;
}
What am I doing wrong?

After
std::vector<float> some_vec;
your vector is empty. You must not access any element in it then, because there isn't any.
If you want to put values into it, you need to append them to the vector using push_back()
for (some iterator loop here)
{
//snip
some_vec.push_back(some_float);
i++;
}
Alternatively, if you know the size in advance, and if the construction of dummy values in the vector is cheap (as it is for float and other built-ins), you can resize() the vector in advance
some_vec.resize(42);
or create it with the right amount of elements
std::vector<float> some_vec(42);
Given either of the two above, you can then access elements 0..41 in the vector.

call resize() function on your vector and then call push_back() to add elements. After this you can access elements using indexing.

Possibly a problem elsewhere in code we can't see, but mostly likely given you've not called resize(), push_back() or insert() that i is outside of the vector. Use some_vec.at(i) = some_float; to check that i is within the valid range for the vector.

My guess is that your vector is empty. Use push_back(some_float) to add elements to it.

Related

Unexpected C++ Vector Behavior

For some reason I'm having a discrepancy between the empty() vector operator and what is in the vector.
if(myvector.empty())cout<<"My Vector is empty\n";
cout<<myvector.front()<<endl;
cout<<myvector[0]<<endl;
print(myvector);
print() is my function that simply takes a vector input and prints the vector.
For some reason, my vector, which shouldn't be empty returns empty for myvector.empty(), however it returns the first (and expected) value for myvector.front() and myvector[0], however when printing the entire vector, no contents are printed.
Any ideas?
When vector is empty, you need to let your if statement switch to cout only otherwise the behavior is undefined.
a simple and quick fix is
if(myvector.empty())
{
cout<<"My Vector is empty\n";
}
else
{
cout<<myvector.front()<<endl;
cout<<myvector[0]<<endl;
print(myvector);
}
It sounds like you used reserve to allocate space for your vector but then added elements with operator[] rather than insert or push_back.
In order to actually ADD an element to the vector you need to use one of those methods that does so, not just accessing elements with []. This is why your vector empty call is true. By pure random chance the memory you've allocated does have the values you expect.

c++ vector insertion and reading

I am inserting elements with push_back in a vector. I want to read the data in FIFO and using iterator assigned to begin of vector. Is there any other approach of reading data in FIFO in a vector?
You may use a std::deque() and its pop_front() method.
You can access the elements of a vecotr just like you would access the elements of an array:
std::vector<std::string> vec;
// Excluded: push items onto vec
for (int i = 0; i < vec.size(); ++i) {
// Example:
std::cout << vec[i];
}
The code would be:
auto value = myvector[0];
myvector.erase(myvector.begin());
However, removing elements from the beginning (or somewhere in between) is slow, because it must copy the whole array. Access is fast though: vector allows random access (i.e. access by any explicit index) in O(1) (i.e. constant access time, i.e. very fast).
But another container structure instead of vector might make more sense for you, e.g. list or deque. Some STL implementations (or other framework) also have something like rope which is in many cases the best of both worlds.
There's nothing special to pay attention to. To insert, use
push_back, to extract, you need something like:
if ( !fifo.empty() ) {
ValueType results = fifo.front();
fifo.erase( fifo.begin() );
}
(Don't forget to check for empty before trying to remove an
element.)
An important point to remember is that both push_back and
in some cases erase can invalidate iterators, so you don't
want to keep iterators into the underlying vector hanging
around.

C++ Regarding assigning value to Vector<Point> myVariable

C++ Regarding assigning value to Vector myVariable
Hi guys.
I have this struct
struct Point
{
int x,y;
}
and in my main.cpp i got something like this
int main()
{
vector<Point> myPoints;
myPoints[0].x = 1;
myPoints[0].y = 1;
myPoints[1].x = 2;
myPoints[1].x = 2;
return 0;
}
and i get segmentation core dump, what is wrong with setting value to the element of the vector.
Thanks for guiding!
vector<Point> myPoints;
creates an empty vector of Point objects. Since it's empty, you can't access myPoint[0], myPoint[1] etc. Attempting to do this won't auto-create elements; instead, it will invoke undefined behaviour – quite typically a segmentation fault.
Use push_back to append elements to the vector:
myPoints.push_back(Point(1,1));
or, alternatively, resize the vector so it contains default-constructed elements:
myPoints.resize(2);
You can also use an argument to the constructor of std::vector to resize it right at initialization time:
vector<Point> myPoints(2); // auto-resizes the vector to length 2
Note about push_back. In C++11, you may use emplace_back() instead of push_back() as well: myPoints.emplace_back(1,1); appends a new element to the vector by calling the Point constructor in-place, using 1,1 as the arguments to the constructor. This is the most efficient way of appending newly created elements to the vector.
You didn't initialize any objects. You need to make the objects and then put them into the vector, otherwise you are acting on something that does not exist, which is causing the segfault.
Example:
Point myPoint;
myPoints.push_back(myPoint);
myPoints[0].x = 1;
The problem is that you are trying to access elements which have not been created yet.
After this line:
vector myPoints;
you have a vector myPoints which has exactly 0 elements. Thus, myPoints[0] is meaningless.
You need to do one of the following:
Create a vector with a pre-determined size: vector<Point> myPoints(2); (note: you can expand or shrink it later), then execute myPoints[0].x=1 etc.
Use the vector's push_back method to add new elements to the vector, i.e. myPoints.push_back(Point(0, 0));
After you declare the new vector object, use the resize method to allocate space for two new elements.

C++ pair data type issue

I am writing a friend recommendation algorithm and in a part I have to store 350 random friendship using the data type std::pair in C++. I basically use an adjacency list (implemented as vector of vectors). I create a vector that stores data type pair<int,int>. I select a random value from the adjacency list and select one of it's friends randomly, however, even though I'm quite sure that I push the data type as pair however I cannot iterate through it.
What could be the possible reason?
int FRIENDS_AND_UNFRIENDS_TO_STORE=350,randomNode=rand()%adjacencyList.size(),randomFriend;
vector< pair<int,int> >listForPR;
listForPR.resize(FRIENDS_AND_UNFRIENDS_TO_STORE*2);
for(int i=0;i<FRIENDS_AND_UNFRIENDS_TO_STORE;i++) {
while(adjacencyList[randomNode].size()<1)
randomNode=rand()%adjacencyList.size();
randomFriend=rand()%adjacencyList[randomNode].size();
listForPR.push_back(make_pair(randomNode,adjacencyList[randomNode][randomFriend]));
}
for(int i=0;i<350;i++)
cout<<"Node #"<<listForPR[i].first<<" & It's Friend: "<<listForPR[i].second<<endl;
Added this and !mysteriously solved the problem;
for(int i=0;i<FRIENDS_AND_UNFRIENDS_TO_STORE;i++) {
while(adjacencyList[randomNode].size()<1)
randomNode=rand()%adjacencyList.size();
randomFriend=rand()%adjacencyList[randomNode].size();
pair<int,int> temp=make_pair(randomNode,adjacencyList[randomNode][randomFriend]);//added
listForPR.push_back(temp);
}
Your vector contains 350/2 = 175 elements that you pushed in during the loop, but you are going through 350 elements when you iterate.
You shouldn't mix resize and push_back.
The first resize fills listForPR with 350 zeroed items.
Then push_back adds items to the end of the vector.
Deleting resize statement should fix the problem. Even better solution is to use reserve (it just prepares buffer in vector for insertion).

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.