How to create a vector of class objects in C++? - c++

I am trying to create a simple stack using vector in C++.
Here is the code:
#include <vector>
class Site
{
public:
int i; // site position i (x-axis)
int s; // site state
vector<Site> neighbors;
Site(void);
Site(int ii, int ss);
void AddNeighbor(Site &site);
};
Site::Site()
{
i = -1;
s = -1;
vector<Site> neighbors;
}
Site::Site(int ii, int ss)
{
i = ii;
s = ss;
}
void Site::AddNeighbor(Site &site)
{
neighbors.push_back(site);
}
void testStack()
{
int tot = 600;
vector<Site> myStack();
int i = 0;
while (i < tot)
{
Site site(i, 1);
myStack.push_back(site);
i++;
}
i = 0;
while (i < tot)
{
Site *site = myStack.back();
myStack.pop_back();
cout << site->i << site->s << endl;
i++;
}
}
Compiler errors:
ising_wolff.cpp: In function ‘void testStack()’:
ising_wolff.cpp:373:17: error: request for member ‘push_back’ in
‘myStack’, which is of non-class type ‘std::vector()’
myStack.push_back(site);
^ ising_wolff.cpp:380:30: error: request for member ‘back’ in ‘myStack’, which is of non-class type ‘std::vector()’
Site *site = myStack.back();
^ ising_wolff.cpp:381:17: error: request for member ‘pop_back’ in ‘myStack’, which is of non-class type
‘std::vector()’
myStack.pop_back();
What do these errors mean?
Here are some sites I have looked at:
1) Creating objects while adding them into vectors
2) push_back causing errors in C
3) how to create vectors of class object

How to create a vector of class objects in C++?
Start with something simpler so you can get the hang of it.
First, create a vector of primitive ints:
#include <vector>
#include <iostream>
using namespace std;
int main(){
vector<int> sites(5);
sites.push_back(5);
for(int x = 0; x < sites.size(); x++){
cout << sites[x];
}
cout << endl;
return 0;
}
Compiling it:
g++ -o test test.cpp
Running it:
./test
000005
Create a vector of class objects in a similar way as above:
#include <iostream>
#include <vector>
using namespace std;
class Site {
public:
int i;
};
int main() {
vector<Site> listofsites;
Site *s1 = new Site;
s1->i = 7;
Site *s2 = new Site;
s2->i = 9;
listofsites.push_back(*s1);
listofsites.push_back(*s2);
vector<Site>::iterator it;
for (it = listofsites.begin(); it != listofsites.end(); ++it) {
cout << it->i;
}
return 0;
}
Which should print:
79

vector<Site> myStack();
This is actually a function declaration. The function is called myStack and it returns a vector<Site>. What you actually want is:
vector<Site> myStack;
The type of neighbours at the moment will store copies of the objects, not references. If you really want to store references, I recommend using a std::reference_wrapper (rather than using pointers):
vector<reference_wrapper<Site>> neighbors;

vector<Site> myStack();
This is wrong. Lose the ().
You're declaring a function, not a vector.
Just write:
vector<Site> myStack;

You could use:
vector<Site> myStack;
myStack.resize(100); //will create 100 <Site> objects

Related

Discerning between struct indexing and size initialization

I'm trying to write a function that takes an array of structs and will sort the elements of the array alphabetically by accessing the first data member. I'm struggling to get the code to distinguish between when I'm referring to a data member versus initializing the size of an array. For example, the following code
void selectionSort(struct A[], int size)
{
int mindex;
for (int ct1 = 0; ct1 < size - 1; ct1++)
{
mindex = ct1;
for (int ct2 = ct1 + 1; ct2 < size; ct2++)
if (A[ct2].state < A[mindex].state)
mindex = ct2;
swap(A[mindex], A[ct1]);
}
}
complains that ct2 is not constant, when I'm clearly using it as an index. How would I get this to run correctly? That is, how can I get it to compare data members in their respective indices rather than think I'm initializing the size of a struct variable?
Edit The error message I am receiving is expression must have a constant value for the variable ct2.
I think you might have a problem with how you're creating your function. Usually, when you declare an array of structs it looks like this.
struct Student {
int uid;
string name;
};
Student studentArry[3];
You would use 'Student' or the name of your struct to initialize your array. For example, int arr[10] is an integer array of size 10 while Student arr[10] is a student array of size 10.
One other side note, if you're trying to create a function that is passed a struct you have to initialize the struct before you define the function. This code will work because the struct was declared before the function was.
#include <iostream>
using namespace std;
struct Student {
int uid;
string name;
};
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
The code below will not because the print function doesn't know what type student is.
#include <iostream>
using namespace std;
void print(Student array[], int size){
for(int i = 0; i < size; i++){
cout << array[i].uid << endl;
cout <<array[i].name<< endl;
}
};
int main(){
struct Student {
int uid;
string name;
};
Student StudentRecords[2] = {
{19, "John Smith"},
{21, "Jim Pop"}
};
print(StudentRecords, 2);
return 0;
}
So, all in all, I think you need to change how you're creating the parameter for the function and possible where you're declaring your struct.

C++, Weird behavior of cout when trying to print integers

Im trying to write a class that stores an id and a value in an container class.
Im using an nested class as my data structure.
When im compiling the code sometimes it prints perfectly, sometimes it prints nothing and sometimes it prints half of the data then stops.
When i debug the code the same weird behavior occours, when it fails during debug it throws an error "Map.exe has triggered a breakpoint.", the Error occours in the print method when im using cout.
cmap.h
#pragma once
class CMap
{
public:
CMap();
~CMap();
CMap& Add(int id, int value);
void print() const;
private:
class container
{
public:
~container();
int container_id = 0;
int container_value = 0;
};
container* p_komp_;
int dim_ = -1;
void resize();
};
cmap.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
CMap::CMap()
{
p_komp_ = new container[0];
}
CMap::~CMap()
{
p_komp_ = nullptr;
cout << "destroy cmap";
}
CMap& CMap::Add(int id, int value)
{
resize();
p_komp_[dim_].container_id = id;
p_komp_[dim_].container_value = value;
return *this;
}
void CMap::resize()
{
container* temp_array = new container[++dim_];
if (dim_ == 0)
{
temp_array[0].container_id = p_komp_[0].container_id;
temp_array[0].container_value = p_komp_[0].container_value;
}
for (unsigned i = 0; i < dim_; i++)
{
temp_array[i].container_id = p_komp_[i].container_id;
temp_array[i].container_value = p_komp_[i].container_value;
}
p_komp_ = temp_array;
}
void CMap::print() const
{
for (unsigned i = 0; i <= dim_; i++)
{
cout << p_komp_[i].container_id;
cout << p_komp_[i].container_value;
}
}
CMap::container::~container()
{
cout << "destruct container";
}
Map.cpp
#include "cmap.h"
#include <iostream>
using namespace std;
void main(void)
{
CMap m2;
m2.Add(1, 7);
m2.Add(3, 5);
m2.print();
}
These two things are a possible reason for your problem:
int dim_ = -1;
and
container* temp_array = new container[++dim_];
When you allocate, you increase dim_ from -1 to 0. That is you create a zero-sized "array", where every indexing into it will be out of bounds and lead to undefined behavior.
You also have memory leaks since you never delete[] what you new[]. I didn't look for more problems, but there probably a more.
And an "array" (created at compile-time or through new[]) will have indexes from 0 to size - 1 (inclusive). You seem to think that the "size" you provide is the top index. It's not, it's the number of elements.
It seems to me that you might need to take a few steps back, get a couple of good books to read, and almost start over.

How to pass in an array of objects: error c2146: syntax error : missing ')' before identifier 'myMembers'

I'm a c++ student and this is my first post here.
I have an array containing Member objects (which will be dynamic in the future). I'm trying to pass the array into a function, getLogin in my case.
I think I have some of the syntax wrong, I'm still struggling to understand dynamic arrays and correct syntax for pointers in different situations. Visual Studio is showing an error with myMembers, where it is written as a parameter for getLogin.
#include <iostream>
#include <string>
#include "Member.h"
using namespace std;
int getLogin( const int, Member[] );
int main(){
int numAccounts = 0;
int accCapacity = 5;
int currentAcc = 0;
Member member[5];
currentAcc = getLogin( numAccounts, member );
return 0;
}
int getLogin( const int lastAcc, Member[] myMember ){
int accNum;
cout << "account number:" << endl;
cin >> accNum;
if( accNum > 0 && accNum <= lastAcc ){
myMember[accNum].setLoggedIn( true );
}
else{
accNum = 0;
}
return accNum;
}
(p.s. What I really want is a pointer to the array, because I don't want a copy of the entire array to be created. However, I believe that using the array name is actually like using a pointer to the first element. So I think I don't need to worry about that.)
Change the definition of getLogin() as follows:
int getLogin( const int lastAcc, Member myMembers[] ){
//...
}
(And of course you should better use std::vector or std::array, but since this is a homework, this advice probably makes no sense)
If you want to pass an array of pointers then you have to change
the implementation of your function getLogin:
int getLogin( int lastAcc, Member** myMembers )
{
int accNum;
if( accNum > 0 && accNum <= lastAcc )
{
myMembers[accNum]->setLoggedIn( true );
}
else{
accNum = 0;
}
return accNum;
}
and this is how you pass an array to it:
int numAccounts = 0;
int accCapacity = 5;
int currentAcc = 0;
Member* members[numAccounts];
for ( int i =0; i < numAccounts; i++)
{
members[i] = new Member();
}
currentAcc = getLogin( numAccounts, members )

c++ segmentation fault for dynamic arrays

I want to add a theater object into a boxoffice object in a C++ code. When I try to add it in main code, first one is added successfully. But a segmentation fault occurs for second and obvioulsy other theater objects. Here is the add function;
#include <iostream>
#include <string>
#include "BoxOffice.h"
using namespace std;
BoxOffice::BoxOffice()
{
sizeReserv = 0;
sizeTheater = 0;
theaters = new Theater[sizeTheater];
reserv = new Reservation[sizeReserv];
}
BoxOffice::~BoxOffice(){}
void BoxOffice::addTheater(int theaterId, string movieName, int numRows, int numSeatsPerRow){
bool theaterExist = false;
for(int i=0; i<sizeTheater; i++)
{
if(theaters[i].id == theaterId)
{
theaterExist=true;
}
}
if(theaterExist)
cout<<"Theater "<<theaterId<<"("<<movieName<<") already exists"<< endl;
else
{
++sizeTheater;
Theater *tempTheater = new Theater[sizeTheater];
if((sizeTheater > 1)){
tempTheater = theaters;
}
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
delete[] theaters;
theaters = tempTheater;
cout<<"Theater "<<theaterId<<"("<<movieName<<") has been added"<< endl;
cout<<endl;
delete[] tempTheater;
}
}
And I get segmentation fault on this line;
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
This is Theater cpp;
#include "Theater.h"
using namespace std;
Theater::Theater(){
id=0;
movieName="";
numRows=0;
numSeatsPerRow=0;
}
Theater::Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow)
{
id = TheaterId;
movieName = TheaterMovieName;
numRows = TheaterNumOfRows;
numSeatsPerRow = TheaterNumSeatsPerRow;
theaterArray = new int*[TheaterNumOfRows];
for(int i=0;i<TheaterNumOfRows;i++)
theaterArray[i]= new int[TheaterNumSeatsPerRow];
for(int i=0; i<TheaterNumOfRows;i++){
for(int j=0;j<TheaterNumSeatsPerRow;j++){
theaterArray[i][j]=0;
}
}
}
This is header file of Theater;
#include <iostream>
#include <string>
using namespace std;
class Theater{
public:
int id;
string movieName;
int numRows;
int numSeatsPerRow;
int **theaterArray;
Theater();
Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow);
};
And this is how i call add functions;
BoxOffice R;
R.addTheater(10425, "Ted", 4, 3);
R.addTheater(8234, "Cloud Atlas", 8, 3);
R.addTheater(9176, "Hope Springs",6,2);
The problematic lines are these:
if((sizeTheater > 1)){
tempTheater = theaters;
}
First you allocate memory and assign it to tempTheater, but here you overwrite that pointer so it will point to the old memory. It does not copy the memory. Since the code is for a homework assignment, I'll leave it up to you how to copy the data, but I do hope you follow the rule of three for the Theater class (as for the BoxOffice class) which will make it very simple.
Also, there's no need to allocate a zero-size "array", just make the pointers be nullptr (or 0).

C++ code pass compling but return Segmentation fault

I have the following C++ code for practising sequence list and it passed the complier. However, when I try to run it, it returns Segmentation fault. Please help!! Thanks a lot.
main.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
int main() {
SeqList seq;
string vv[] = {"a", "b", "c", "d"};
for (int i = 0; i< 4; i++) {
seq.addElement(vv[i], i);
}
string* v = seq.getSeq();
for (int i=0; i<seq.getSeqSize(); i++) {
cout << v[i] <<endl;
}
return 0;
}
SeqList.h
#include<iostream>
#include<string>
using namespace std;
class SeqList {
private:
string seq[];
int size;
public:
void addElement(string, int);
void delElement(string, int);
string* getSeq();
int getSeqSize();
};
SeqList.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
string seq[100];
int size = 0;
string* SeqList::getSeq(){
return seq;
};
int SeqList::getSeqSize(){
return size;
};
void SeqList::addElement(string str, int pos) {
int i;
for (i = size; i > pos; i--) {
seq[i] = seq[i-1];
}
seq[i-1] = str;
size++;
};
Your segfault is happening because you're trying to access seq[i-1] in addElement when i = 0. This tries to access the memory outside of seq which causes a segfault. Try using seq[i] and seq[i+1] instead of seq[i-1] and seq[i], though you'll have to make sure you never call that code with more than 99 values or you'll run into a similar problem where the program tries to access memory past the end of seq.
Also, in SeqList.cpp
string seq[100];
int size = 0;
These lines are creating new variables, when it looks like you're trying to change the values you made in SeqList.h. To change those private values in your class you should either use a constructor or other function to initialize the values.