Error adding n enum namespace inside structure - c++

I have an error when I add a parameter of class inside the structure. I don't know why, but inserting a simple variable of type namespace::enum variable with a static_cast doesn't make an error. What I try to do, is to insert all my enums in a vector of structure
namespace code
namespace plazza {
enum Ingredients {
Doe,
Tomato,
Gruyere,
Ham
};
}
Structure
typedef struct s_stock {
plazza::Ingredients ingredient;
int quantity;
} t_stock;
Class
class Kitchen {
public:
Kitchen(int multiplier, int numCooks, int cookingTime);
~Kitchen();
private:
int _multiplier;
int _numCooks;
int _cookingTime;
std::vector<t_stock> _stock;
plazza::Ingredients ginger;
};
Code
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime) {
_multiplier = multiplier;
_numCooks = numCooks;
_cookingTime = cookingTime;
// How I think it should be
_stock[0].ingredient = plazza::Doe;
// No error
ingre = static_cast<plazza::Ingredients>(plazza::Ingredients::Doe);
// what I try but error
_stock[0].ingredient = static_cast<plazza::Ingredients>(plazza::Ingredients::Doe);
}
Error adding into the vector of structure
==7692== Invalid write of size 4
==7692== at 0x110A7E: Kitchen::Kitchen(int, int, int) (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== by 0x10CE96: Reception::time_to_work() (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== by 0x10C16B: main (in /home/jonathangomez/epitech/2/ccp/CCP_plazza_2019/plazza)
==7692== Address 0x0 is not stack'd, malloc'd or (recently) free'd

You are assigning a value to _stocks[0] but you aren't sizing your vector first to contain at least one element. Either use push_back or use an initialization list to initialize your vector at construction.
To assign something to a t_stock you can use
t_stock dummy = { plazza::Doe /* first argument in struct is the ingredient */, 1 /*second argument in the struct is the quantity */ }
Combined, to assign everything properly in your Kitchen constructor, you could use:
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime)
: _multiplier(multiplier),
_numCooks(numCooks),
_cookingTime(cookingTime),
_stock({ {plazza::Doe, 1} }) // Initialize vector with one element
{
}
To add multiple elements at creation you can do:
Kitchen::Kitchen(int multiplier, int numCooks, int cookingTime)
: _multiplier(multiplier),
_numCooks(numCooks),
_cookingTime(cookingTime),
_stock({ {plazza::Doe, 1}, {plazza::Tomato, 4} }) // Initialize vector with two elements
{
}
To add new stock elements after creation, always use push_back
_stock.push_back({plazzo::Gruyere, 16}); // Add lots of 'em

Related

How to access and store struct members of vector type?

I have a function in a common module(class) which takes a struct reference of vector type:
The structure has an element which is of Vector type.
Please refer following code snippet:
bool getFrameInfo(ABC& abc);
struct ABC {
int numberOfFrames;
std::vector<XYZ> framInfo;
....
}
struct XYZ {
int size;
Position Pos;
...
}
I need to access and store members of struct XYZ in member variables or local variables in my class which calls the function defined in the common module to get frame information.
Please suggest ways to access and store "XYZ" struct members so that I can use them repeatedly in my program to draw a frame.
Example:
bool getFrameInfo(ABC& abc) {
abc.framInfo[0].size = 10;
// more code, where you return something somewhere
}
This will access your vector from abc, then index its first element (I assume it exists), and access the size field of the first struct of your vector. It stores 10 in its size.

How can I check if a vector with a custom class is NULL?

I have made this custom class
#ifndef VEHICLE_H_
#define VEHICLE_H_
Class Vehicle {
public:
Vehicle();
Vehicle(char,char,int,int);
virtual ~Vehicle();
char getLicense_plate();
void setLicense_plate(char);
char getBrand();
void setBrand(char);
int getTime_in();
void setTime_in(int);
int getTime_out();
void setTime_out(int);
char license_plate;
char brand;
int timei;
int timeo;
};
And I have created a Vehicle vector with size 50 in the main.cpp but I don't how to check each value if they are empty.
#inlcude<iostream>
#include<vector>
#include<algorithm>
#inlude "Vehicle.h"
using namespace std;
int main()
{
vector<Vehicle> avai_space(50);
for(int i=0;i<avai_space.size();i++)
{
//if(avai_space(i) == NULL??){}
vector<Vehicle> avai_space(50); does not create an empty vector with a storage capacity of 50; it creates a vector with 50 valid entries where each entry gets initialized using the default constructor of Vehicle class.
To create an empty vector with max storage of 50, use:
vector<Vehicle> vehicle_vec;
vehicle_vec.reserve(50);
You can use vehicle_vec.push_back() to add items into the vector without affecting the storage.
Once the vector is populated with entries, you can now use vehicle_vec.size() to iterate through the valid entries in this vector:
for (size_t i = 0 ; i < vehicle_vec.size() ; i++) {
// Use vehicle_vec[i], for e.g.
std::cout << vehicle_vec[i].brand << "\n";
}
vector<Vehicle> avai_space(50); creates 50 Vehicles. They exist after this line and are not empty, but what ever Vehicle's default constructor makes them.
If you want to store Vehicles in your vector, but not create them yet (I assume that's what you mean with == NULL), just write vector<Vehicle> avai_space; and then add new Vehicless to the end with std::vector::push_back.
None of the elements will ever be 'empty', as in a null pointer, because they're stored by value, not by pointer.
That scenario would correspond to a declaration like
std::vector<Vehicle*>
or, if the pointers need to own the objects
std::vector<std::unique_ptr<Vehicle>>

How to Access a Struct Inside a Struct in C++?

I'm trying to access the variables string ModelName and int Sales like this Dealer.Modelo.ModelName but it's not working. How can I access those variables to fill the the structure?
PD: The compiler says that "Dealer" should have a class type.
const int MAXIMODEALERS = 20;
const int MAXIMOMODELOS = 6;
struct Detail
{
string ModelName;
int Sales;
};
struct Element
{
string CompanyName;
Detail Modelo[MAXIMOMODELOS];
};
Element Dealer[MAXIMODEALERS];
Element Dealer[MAXIMODEALERS];
declares an array of objects of type Element, but :
Dealer.Modelo.ModelName = "something";
is treating Dealer as it would be a single instance of Element, neither an array. You need to use an index to access concrete element (same for the Modelo):
Dealer[SomeIndex].Modelo[OtherIndex].ModelName = "something";

Vector of structs initialization

I want know how I can add values to my vector of structs using the push_back method
struct subject
{
string name;
int marks;
int credits;
};
vector<subject> sub;
So now how can I add elements to it?
I have function that initializes string name(subject name to it)
void setName(string s1, string s2, ...... string s6)
{
// how can i set name too sub[0].name= "english", sub[1].name = "math" etc
sub[0].name = s1 // gives segmentation fault; so how do I use push_back method?
sub.name.push_back(s1);
sub.name.push_back(s2);
sub.name.push_back(s3);
sub.name.push_back(s4);
sub.name.push_back(s6);
}
Function call
setName("english", "math", "physics" ... "economics");
Create vector, push_back element, then modify it as so:
struct subject {
string name;
int marks;
int credits;
};
int main() {
vector<subject> sub;
//Push back new subject created with default constructor.
sub.push_back(subject());
//Vector now has 1 element # index 0, so modify it.
sub[0].name = "english";
//Add a new element if you want another:
sub.push_back(subject());
//Modify its name and marks.
sub[1].name = "math";
sub[1].marks = 90;
}
You cant access a vector with [#] until an element exists in the vector at that index. This example populates the [#] and then modifies it afterward.
If you want to use the new current standard, you can do so:
sub.emplace_back ("Math", 70, 0); // requires a fitting constructor, though
or
sub.push_back ({"Math", 70, 0}); // works without constructor
.
You may also which to use aggregate initialization from a braced initialization list for situations like these.
#include <vector>
using namespace std;
struct subject {
string name;
int marks;
int credits;
};
int main() {
vector<subject> sub {
{"english", 10, 0},
{"math" , 20, 5}
};
}
Sometimes however, the members of a struct may not be so simple, so you must give the compiler a hand in deducing its types.
So extending on the above.
#include <vector>
using namespace std;
struct assessment {
int points;
int total;
float percentage;
};
struct subject {
string name;
int marks;
int credits;
vector<assessment> assessments;
};
int main() {
vector<subject> sub {
{"english", 10, 0, {
assessment{1,3,0.33f},
assessment{2,3,0.66f},
assessment{3,3,1.00f}
}},
{"math" , 20, 5, {
assessment{2,4,0.50f}
}}
};
}
Without the assessment in the braced initializer the compiler will fail when attempting to deduce the type.
The above has been compiled and tested with gcc in c++17. It should however work from c++11 and onward. In c++20 we may see the designator syntax, my hope is that it will allow for for the following
{"english", 10, 0, .assessments{
{1,3,0.33f},
{2,3,0.66f},
{3,3,1.00f}
}},
source: http://en.cppreference.com/w/cpp/language/aggregate_initialization
You cannot access elements of an empty vector by subscript.
Always check that the vector is not empty & the index is valid while using the [] operator on std::vector.
[] does not add elements if none exists, but it causes an Undefined Behavior if the index is invalid.
You should create a temporary object of your structure, fill it up and then add it to the vector, using vector::push_back()
subject subObj;
subObj.name = s1;
sub.push_back(subObj);
After looking on the accepted answer I realized that if know size of required vector then we have to use a loop to initialize every element
But I found new to do this using default_structure_element like following...
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
typedef struct subject {
string name;
int marks;
int credits;
}subject;
int main(){
subject default_subject;
default_subject.name="NONE";
default_subject.marks = 0;
default_subject.credits = 0;
vector <subject> sub(10,default_subject); // default_subject to initialize
//to check is it initialised
for(ll i=0;i<sub.size();i++) {
cout << sub[i].name << " " << sub[i].marks << " " << sub[i].credits << endl;
}
}
Then I think its good to way to initialize a vector of the struct, isn't it?

C++ setting array values in a class

I am having trouble with what seems like a very simple concept. I have a class like such:
class Projectile
{
public:
int count;
int projectiles[1][3];
Projectile();
void newProjectile();
};
Projectile::Projectile()
{
count = 0;
}
void Projectile::newProjectile()
{
projectiles[0][0] = { 1, 2, 3 };
}
I am trying to set the values inside the projectiles array, and I must be doing this incorrectly. How can I go about dynamically adding a set of values into this property?
projectiles[0][0] refers to a specific location in a two-dimensional array, its type is int
If you want to dynamically add items, then you can use std::vector<int> (see here)
projectiles[0][0] = { 1, 2, 3 };
This isn't correct. Initializer lists can only given at the point of declaration. You have to assign values independently to each location of the array elements. std::vector<std::vector> twoDimArray; is what you want.
struct foo{
std::vector<std::vector<int> > twoDimArray;
void create(int size){
std::vector<int> oneDimArray(size);
// vector as of now can just accommodate size number of elements. They aren't
// assigned any values yet.
twoDimArray.push_back(oneDimArray); // Copy it to the twoDimArray
// Now if you wish to increase the size of each row, just push_back element to
// that row.
twoDimArray[0].push_back(8);
}
};
try this
void Projectile::newProjectile()
{
projectiles[0][0] = 1;
projectiles[0][1]=2;
projectiles[0][2]=3;
}