C++ reading and writing problems in using std::vector with classes - c++

I have this class in a hpp file:
class info
{
public:
float lux[100];
float pwm[100];
float time[100];
float ref_lux;
int counter_samples_stream;
};
In the cpp file that contains this header, I create a vector of this class and because I put it in the beginning of the cpp file it is a global variable. This is the code I use to create it:
std::vector <info*> vect_node[3]; //creates 3 instances of class info in a vector
Inside the function(called abc) we are changing and initializing the vector's data by doing per example this: vect_node[1].lux[0] = 25; .
We are also trying to access the vector's data in another function(called zys) but when trying to access it the program crashes and returns core dumped.
Neither function abc or zys pass the vect_node in its arguments. The doubt is how can I write in vec_nodein a function in a way it changes its values permanently(and not only in the function) and read from this vector now updated in another function(syz).

The syntax std::vector<info*> vect_node[3]; will create an array of 3 std::vectors, in the same way that int my_array[3]; declares an array of 3 ints.
If you want to create a single std::vector with an initial capacity of 3, use the fill constructor. For example,
std::vector<info*> vect_node{3, nullptr};
will construct a std::vector called vect_node with an initial capacity of 3, where every element in the vector is of type info* has the initial value nullptr.
As pointed out in the comments, if you do not want a vector of pointers, you can instead use
std::vector<info> vect_node{3};
In this case, a std::vector of size 3 will be created called vect_node. Each element of the vector will contain an info object. Using this approach, your
vect_node[1].lux[0] = 25;
will now be valid.
Documentation for the std::vector constructors can be found here.

One way to easily initialise your vector of pointers is to use smart pointers so in one line you can do:
std::vector<std::shared_ptr<info>> vect_node(3, std::make_shared<info>());
Which will create a vector of three smart pointers and allocate the memory. You will then be able to just discard the vector without much worrying. You can modify elements with vect_node[O]->lux[0] = 10;
You just need to create a constructor for your class info.

Related

how to push_back vector with no size in a specific location?

I'm trying to get a solid understanding of Vectors. So i understand if we init vectors as following we specify the exact location in array for the vector to exist
vector<int> temp[5];
temp[i].push_back(randomInt);(i a random position)
but what if i'm trying to have a vector without specified size because i do not know the amount of input? how would i define the first index for example of temp as i did previously using the following init?
vector<int> temp;
here:
vector<int> temp[5];
you declared an array of 5 vectors, but going by your description it looks like you're meant to declare one vector with pre-allocated 5 elements (if so, then it should have been like vector<int> temp(5);)
how would i define the first index for example of temp as i did
previously using the following init?
all the std containers have methods allowing you to push / emplace data (i.e. to extend them) and method size() allowing to check the current size of the container.

How to convert column vector into MxN matrix?

I am relatively new to C++ and kind of stuck in this problem. I have 999x1 vector of point coordinates and I want to convert it in 333x3 matrix dyanamically. Besides this, I am using different Cpp files for one project so the function which reads the points set is in different file. How to make this matrix and how should I access it in my main code?
I tried using vector<vector<float> > Mymatrix thing but you need to specify the rows and column size in this kind of definition which I cannot get until I read the file. If I try to declare above Mymatrix variable in the function which is reading the pointset file, its scope gets limited and I cannot use that Mymatrix in main.cpp.
Its little bit difficult to write the code here because it has many links with other files. I hope you have got my problem! Please help me in this issue...Thanks in advance!
vector is really just a container for array. So basically what you have is a int A[999] and want to convert this into int M[333][3];
Considering that in memory both a 1D and a 2D array are stored in a contiguous memory region, you can achieve this in several ways:
- use a pointer and two indexes i, j: the first 3 elements are your first row,
the next 3 elements your second row and so on.
int vector<int> v;
int *p, i=0,j=0; // i=[0..332], j=[0..2]
p=&v[0];
*(p+(i*3)+j); //this is the same as p[i][j];
Or declare matrix (either allocate static or dynamic memory for it) and copy all the elements int the matrix:
int M[333][3]; //i'll go with static allocation for this example
for(i=0;i<333;i++)
for(j=0;j<3;j++)
M[i][j] = v[i*3 + j];
choose which ever method you want - the advantage of the first one is that it does not us the extra memory.
You can create your MyMatrix as a pointer and pass to your function as parameter:
vector<vector<float> >* Mymatrix; //Don't forget to initialize the pointer
functionThatReadsFiles(Mymatrix); //That function makes changes to Mymatrix
With this, any changes you make to Mymatrix inside "functionThatReadsFiles" will remain after its call. Anyway, make sure you fully understand how to operate with pointers before trying this.
As #erlc says, you can also declare your function with:
void functionThatReadsFiles(vector<vector<float> >& Mymatrix);
And call just call it normally (without pointers), and again the changes will remain into your Mymatrix.

C++ - Define Vector size with class argument

Hello I'm trying to create a genetic algorithm with C++ and I tried to use vector as the container the problem is I didn't know how to set the size of the vector because the vector have a class argument like this
class population
{
friend class chromosome;
private:
int population_number;
int best_index[2];
vector <chromosome *> chromosome_population;
public:
population(int numberOfPopulation);
population(int numberOfPopulation,int numberOfSynapse);
~population();
int worst_chromosome();
void mating();
void crossover(int parent_1,int parent_2);
};
this is the population class and here's the chromosome class
class chromosome
{
friend class population;
private:
int chromosome_id;
float fitness;
vector <gen *> gen_chromosome;
public:
chromosome();
~chromosome();
void fitness_function();
void mutation_translocation();
int get_chromosome_size();
};
how can I set the vector length in the population class constructor? I've tried to use vector.pushback and vector.resize but both will give me error because the argument doesn't match. Actually I'm understand why it become error but I didn't know how to match the argument inside the vector pushback here's my population constructor
population::population(int numberOfPopulation)
{
srand (time(NULL));
population_number = numberOfPopulation;
for(int a=0;a<population_number;a++)
{
chromosome_population.push_back();
}
cout<<chromosome_population.size();
for(int i=0;i<population_number;i++)
{
chromosome_population[i]->chromosome_id = i;
int chromosome_length = rand() % 10 + 1;
for(int j=0;j<chromosome_length;j++)
{
chromosome_population[i]->gen_chromosome[j]->basa_biner = rand()%1;
chromosome_population[i]->fitness = (rand()%99)+1;
}
}
}
If is there any other information you want you can tell me in the comment and I'll add the information you needed. Thanks before.
std::vector has several constructors and one of the variants accepts the initial number of elements to be stored in the vector.
Specify the size of the vector in the population constructor's initializer list:
population::population(int numberOfPopulation) :
population_number(numberOfPopulation),
chromosome_population(numberOfPopulation)
{
}
Give this approach, the population_number member variable is unnecessary as it can be obtained by chromosome_population.size().
Specifying an initial size on the vector will mean that it contains numberOfPopulation null pointers. Before accessing elements in the vector you need to create objects, in this case using new. If the elements are copyable and polymorphic behaviour is not required then recommend using vector<chromosome> instead. If you must use dynamically allocated elements in the vector then you must allocate first:
chromosome_population[i] = new chromosome();
and remember to delete when no longer required.
It also desirable to use a form of smart pointer instead of raw pointers. An advantage of using the smart pointer is that when the vector<unique_ptr<chromosome>> goes out of scope the elements will be destructed for you, without having to explicitly call delete on each of the elements. See What C++ Smart Pointer Implementations are available? for a useful listing of the available smart pointers.
Note that vector::push_back() accepts an argument, with same type as its element. So the correct invocation of push_back() is:
chromosome_population.push_back(new chromosome());
If you specify an initial size of the vector at construction, calling push_back() will add elements after the initial (null pointers in this case) elements in the vector.

Adding element to Array of Objects in C++

How do I add an element to the end of an array dynamically in C++?
I'm accustomed to using vectors to dynamically add an element. However, vectors does not seem to want to handle an array of objects.
So, my main goal is having an array of objects and then being able to add an element to the end of the array to take another object.
EDIT**
Sorry, its the pushback() that causes me the problems.
class classex
{
private:
int i;
public:
classex() { }
void exmethod()
{
cin >> i;
}
};
void main()
{
vector <classex> vectorarray;
cout << vectorarray.size();
cout << vectorarray.push_back();
}
Now I know push_back must have an argument, but What argument?
Now I know push_back must have an argument, but What argument?
The argument is the thing that you want to append to the vector. What could be simpler or more expected?
BTW, you really, really, really do not want exmethod as an actual method of classex in 99% of cases. That's not how classes work. Gathering the information to create an instance is not part of the class's job. The class just creates the instance from that information.
Arrays are fixed sized containers. So enlarging them is not possible. You work around this and copy one array in a bigger and gain space behind the old end, but that's it.
You can create a array larger than you currently need it and remember which elements are empty. Of course they are never empty (they at least contain 0's), but that's a different story.
Like arrays, there are many containers, some are able to grow, like the stl containers: lists, vectors, deques, sets and so on.
add a Constructor to set i (just to give your example a real world touch) to your example classex, like this:
class classex {
public:
classex(int& v) : i(v) {}
private:
int i;
};
An example for a growing container looks like this:
vector <classex> c; // c for container
// c is empty now. c.size() == 0
c.push_back(classex(1));
c.push_back(classex(2));
c.push_back(classex(3));
// c.size() == 3
EDIT: The question was how to add an element to an array dynamically allocated, but the OP actually mean std::vector. Below the separator is my original answer.
std::vector<int> v;
v.push_back( 5 ); // 5 is added to the back of v.
You could always use C's realloc and free. EDIT: (Assuming your objects are PODs.)
When compared to the requirement of manually allocating, copying, and reallocating using new and delete, it's a wonder Stroustrup didn't add a keyword like renew.

How to store an unknown number of elements in an array C++

Sorry if the title is not clear but I ll explain now my problem. I am new in C++.
I have created a class in C++. Instances of that class are the input of the program and they have to be stored in an array to perform the calculations. The problem is that the number of instances of that class that have to be defined by the user is fixed for a single run but can vary from run to run. Here an example:
#include <<blablah>blahblah>
int main()
{
int number_of_instances = 3;
MyClass first_instance(one_parameter_1, another_parameter_1);
MyClass second_instance(one_parameter_2, another_parameter_2);
MyClass third_instance(one_parameter_3, another_parameter_3);
///////////////////
NOW I HAVE TO STORE ALL THREE IN AN ARRAY LIKE
MyClass array[number_of_instances] = {first_instance, second_instance, third_instance};
THE PROBLEM IS THAT I DO NOT KNOW BEFORE HAND HOW MANY OF THEM ARE THE USER IS GOING TO INPUT
///////////////////
performCalculations(array);
return 0;
}
Thanks a lot in advance.
The typical C++ solution is to use a vector.
vector<MyClass> v;
v.push_back(first_instance); //add an already instantiated object to the end of the vector
v.push_back(second_instance);
v.push_back(third_instance);
You won't have to worry about memory management and you are able to access the vector like you would a normal array:
v[0].classMember
You can also add items to the vector in a loop if needed like so:
for(int i = 0; i < 5; i++){
v.push_back( MyClass(i, param2) );
}
And all the objects will be destructed when the vector goes out of scope if you're storing the objects directly in the vector.
One of the downsides to storing the objects directly in the vector is passing the vector as a parameter to a function. This will be a slow operation since the vector (and all the objects it holds) will have to be copied.
If you know the number of instances before you read them all in then you can allocate an array on the heap using new[]. (Don't forget to delete[] them when you've finished.) Note that this requires that the object have a default constructor.
you should use std::vector in this case rather than a built-in array.
#include <vector>
...
std::vector<MyClass> v = {first_instance, second_instance, third_instance};
...
v.push_back(fourth_instance);
If you don't know how many elements the array will contain, I would use a std::vector instead of a plain array as the vector will grow to accommodate the additional elements.
What you want is the Vector class from the standard template library, it behaves like an array but it will re-size itself if you fill it's internal allocation. If you do not need random access to it (i.e. use the [] opperator) you may want to use the List class instead. If you use List you will need to create an enumerator to step through it.
use std::vector<MyClass>, vector template can be found in <vector> header. YOu must learn a little bit to code well, before coding use any of online available c++ FAQs