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

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.

Related

In C++, How do I store values into a vector that is inside of a vector when the two vectors are of different types?

I am writing a program where I need to use the following data structure:
struct shape
{
std::vector<float> verts; // contains the x & y values for each vertex
char type; // the type of shape being stored.
float shapeCol[3]; // stores the color of the shape being stored.
float shapeSize; // stores the size of the shape if it is a line or point
};
In my main program I need a vector of type shape. How would I store values into the vector inside of the struct shapes using the the vector of struct shapes.
For instance, vector<shape> myshapes;
If I wanted to store a value into the first index of my verts vector, inside of my first index of my myshapes vector how would I do this?
in pseudo code it would look something like this, with i being the index:
myshapes[i].vector[i] = 4; // but I know this is incorrect
Would this be easier to implement using a STL list instead and if so what would that syntax look like?
Thanks for the help I am new to vectors so any advice would be appreciated.
vector supports the use of the [] operator. The syntax and semantics are very similar to using the [] operator with arrays. See: http://en.cppreference.com/w/cpp/container/vector/operator_at.
As with any struct member, you need to access it by name. myshapes[i].verts[j] = 4;.
The general advice given is to use std::vector as your default container of choice. Naturally if you have specific needs (like adding/removing items in the middle of the container) other containers may have better performance characteristics.
If your vector(s) start out empty, you'll have to add elements to them before you can index into them with operator[]. This is usually done with push_back (to add an existing shape object) or emplace_back (to construct a new shape object directly in the vector).
Given vector<shape> myshapes, you could add some shapes like this:
// add 10 shapes
for (size_t n = 0; n < 10; n++) {
shape s; // creates a new, blank shape object
// initialize the shape's data
s.type = ...;
s.shapeSize = ...;
// etc.
// add verts
s.verts.push_back(1.0f);
s.verts.push_back(2.0f);
s.verts.push_back(3.0f);
// etc.
// add the shape to the vector
myshapes.push_back(std::move(s));
}
(Since we're done with s on that last line, we can use std::move. This allows push_back to move the shape's data into the vector instead of copying it. Look up move semantics for more info.)
Once you have stuff in the vector, you can access elements by index like this:
myshapes[index of shape].verts[index of vertex within that shape]
Using [] with an invalid index or when the vector is empty invokes undefined behavior (don't do it or your program will crash/malfunction).

how do I empty/clear vector and array in c++

let's say I have a class, A
Class A {
int x[100];
vector<int> y;
Fill(x);
Fill(y.begin());
B(x);
B(y.begin());
}
Class Fill (pointer) {
*pointer = 0;
++pointer;
*pointer = 1;
++pointer
}
Class B(container) {
//how do I clear/empty the array and the vector passed by class A given only the pointers to them?
//I must clear an array and a vector in THIS class.
//I DO NOT want to fill them with 0s.
//x and y.begin are POINTERS to the first element of the container, not containers
}
dsfsdakfgnsdfgsf
dg
sdf
gsdf
ghsdf
g
sdfg
ersg
s
Thank you in advance.
For vector:
some_a_pointer->y.resize(0);
You can't do it with just an iterator (y.begin()).
An array's size can never change, so the best you can do is fill it with 0.
std::vector has a method called clear that will clear all the elements.
So my_vector.clear(); will clear everything. However you can't really do the same for arrays. It's just not possible. At best you can fill them with zeroes or go the wrong way and dynamically allocate the array and then delete it. I would rather not deal with memory issues though so I'd just fill them with zero.
C++11 has a class called std::array<T,N> for static arrays of a compile time size and it has a method called fill that would make filling everything to zero easy (a la looping). You can call it with my_array.fill(0);.

Initializing and setting a vector<int>

vector<int> v;
v.push_back(0); //you have to do this
//v[0] = 0; //this gives you an error
v[0] = 1000000; //but now you can set it
So, how come the first time you initialize a vector, you have to push_back, and after that you can just set it? For a primitive type, say int, you can do int i = 0; for initialization.
If you know in advance the size of your vector, definitively don't use a plain sequence of push_back()'s, since it may be a waste of time reallocating if your vector is large (say, >512 elements).
Better do:
OPTION 1: Preallocating and pushing
vector<int> v;
v.reserve(N); // N is the expected size, but right now [0] is undefined.
for (...) {
v.push_back(...); // No problems in adding more than N elements, but may have to reallocate.
}
OPTION 2: Resizing and filling
vector<int> v;
v.resize(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 3: Create directly with the correct size, then fill
vector<int> v(N);
for (size_t i=0;i<N;i++)
v[i] = ...; // You can't write past N-1 here!
OPTION 4: Create a vector with the correct size and initialized to some fixed value
vector<int> v(N,val); // v[0:N-1] are all equal to val
Because when you first create a vector it is empty so vector[0] doesn't exist. push_back adds an element to the vector then you can modify or read it with vector[i]
Just to make everything 100% clear, your declaration of a vector,
vector<int> v;
is in some sense similar to the declaration of a variable:
int x;
and if you then want, say,
cout << x;
you will get rubbish. Though, if you declare
int x(2);
everything will be fine. Similarly for vectors: declaration of
vector<int> v;
allocates some memory space for a vector, but not fills it. You can then specify
vector<int> v(2);
which means that you now have declared a vector of two elements, or go for a vector-only feature - push_back. This would add elements to your vector, as you've noticed.
Because std::vector<int> isn't std::map<int, int>.
std::vector requires you to manually push_back() or (in C++11) emplace_back() elements for them to be included in the collection. And of course some of its constructors allows you to include initial elements to it. And of course again its assignment operators.
The subscript([]) operator should only be used in reading and/or modifying existing elements. Indexing using operator[] out-of-bounds (non-existent) elements would result in undefined behavior.
You can't access v[0] because there is no v[0] yet. The vector starts off default-constructed as an empty vector. You push an element onto the back and it grows in size by 1. You're then able to access the element you just added. If you want it to start off with one element, use the appropriate constructor:
std::vector<int> v(1); //one zeroed integer
You're comparing apples and oranges. int i = 0; would be like std::vector<int> v;.
You should first allocate memory for setting element values, such as
v.resize(new_size);
or use push_back method to add elements.

How to access an index in a vector without segfaulting

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.

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.