Compile-time error building a simple partial array class in C++ - c++

I'm having trouble getting my Partial Arrays class to compile. In one of my member functions I call for a previous member function and get the error "member reference base type 'ITEM_TYPE [255]' is not a structure or union".
I'm not entirely sure that my member variable declarations are up to snuff, as this is my first time dealing with arrays in C++.
Here is my header:
#ifndef PARTIALARRAY_H
#define PARTIALARRAY_H
#include <iostream>
#include <string.h>
using namespace std;
typedef int ITEM_TYPE;
ITEM_TYPE const MAX = 255;
class PartialArray
{
public:
//-----------------------------------------ctors:-----------------------------------------
PartialArray();
PartialArray(ITEM_TYPE MAX, int numUsed);
//-----------------------------------------member functions:-----------------------------------------
void PrintArray(int a[], int numUsed);
int Search(int a[], int numUsed, ITEM_TYPE key);
int Append(ITEM_TYPE appendMe);
int ShiftRight(int shiftHere);
int ShiftLeft(int shiftHere);
int InsertBefore(ITEM_TYPE insertThis, int insertHere);
int InsertAfter(ITEM_TYPE insertThis, int insertHere);
int Delete(int deleteHere);
string ErrorDescr(int failCode);
private:
//-----------------------------------------member vars:-----------------------------------------
ITEM_TYPE a[MAX];
int numUsed;
};
#endif // PARTIALARRAY_H
And my class declaration (NOTE: the error function and return values are not complete, so those can be ignored):
#include "partialarray.h"
#include <iostream>
#include <string.h>
using namespace std;
//-----------------------------------------ctors:-----------------------------------------
PartialArray::PartialArray()
{
numUsed=0;
}
PartialArray::PartialArray(ITEM_TYPE MAX, int numUsed)
{
numUsed = MAX;
}
//-----------------------------------------member functions:-----------------------------------------
//Prints the array up to its last used element
void PartialArray::PrintArray(ITEM_TYPE a[], int numUsed)
{
for(int i=0; i<numUsed; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
//Searches the array for a particular value and returns the index at which the value first appears
int PartialArray::Search(ITEM_TYPE a[], int numUsed, ITEM_TYPE key)
{
for(int i=0; i<numUsed; i++)
{
if(a[i]==key)
{
return i;
break;
}
else
;
}
return -1; //placeholder for error
}
//Takes a number and appends it to the end of the array after the last interesting element
int PartialArray::Append(ITEM_TYPE appendMe)
{
if(a[numUsed==0])
a[numUsed] = appendMe;
else
return 0; //placeholder for error
return 1; //placeholder for error
}
//Shifts all elements of the array to the right starting at a particular index
int PartialArray::ShiftRight(int shiftHere)
{
ITEM_TYPE save = a[numUsed-1];
for(int i=numUsed; i>=shiftHere; i--)
{
a[i] = a[i-1];
}
a[0] = save;
return 1; //error placeholder
}
//Shifts all elements of the array to the left starting at a particular index
int PartialArray::ShiftLeft(int shiftHere)
{
ITEM_TYPE save = a[0];
for(int i=shiftHere; i<numUsed; i++)
{
a[i] = a[i+1];
}
a[numUsed-1] = save;
return 1; //error placeholder
}
//Takes a number and a position and inserts the number at that position in the array shifting the elements to the right
int PartialArray::InsertBefore(ITEM_TYPE insertThis, int insertHere)
{
a.ShiftRight(insertHere);
a[insertHere] = insertThis;
return 1; //error placeholder
}
//Takes a number and a position and inserts the number at that position in the array shifting the elements to the left
int PartialArray::InsertAfter(ITEM_TYPE insertThis, int insertHere)
{
a.ShiftLeft(insertHere);
a[insertHere] = insertThis;
return 1; //error placeholder
}
//Takes a position and removes that item from the array, shifting all the elements to the left
int PartialArray::Delete(int deleteHere)
{
a[deleteHere] = 0;
a.ShiftLeft(deleteHere);
return 1; //error placeholder
}
string PartialArray::ErrorDescr(int failCode)
{
switch(failCode)
{
case 1:
return "ERROR: etc";
break;
case 2:
return "ERROR: etc";
break;
case 3:
return "ERROR: etc";
break;
case 4:
return "ERROR: etc";
break;
case 5:
return "ERROR: etc";
break;
default:
return "ERROR: etc";
break;
}
}
I have previously built a Rationals class, and I felt solid on that material, but doing something similar with arrays has proven to be a major headache. Any help would be much appreciated!

Most of your code seems ok. However, a is a C-style array, and thus has no member functions.
Thus, the following lines are incorrect:
a.ShiftRight(insertHere);
...
a.ShiftLeft(insertHere);
As you try to use this array with a syntax meaningul only for struct or class variables, the compiler issues here the error message you observe: "member reference base type 'ITEM_TYPE [255]' is not a structure or union"

Related

Segmentation fault: 11 in C++ IntVector

I'm attempting to implement an intvector in C++ and am getting a "Segmentation fault: 11" error. I understand this has something to do with memory management, and considering how new I am to C++ it could definitely be a pretty minor mistake. I debugged the code with valgrind and was given messages such as the following:
Use of uninitialized value of size 8, Invalid read of size 4,Conditional jump or move depends on uninitialized value(s).
My best guess is it has something to do with how I'm implementing the arrays. I originally had the arrays stored on the heap but changed it to the stack and still got the same error. I've already implemented an intvector in java, so I was attempting to use similar logic here, which perhaps is part of the issue.
#include <iostream>
#include "IntVector.h"
#include <cmath>
using namespace std;
int num_elements = 0;
int array_size = 0;
int expansion_factor;
void IntVector::expandArray(){
int tempArr[array_size*2];
for(int i =0;i<array_size;i++){
tempArr[i] = array[i];
}
array = tempArr;
array_size = array_size * 2;
}
void IntVector::add(int val){
int tempArr[array_size];
if(array_size == num_elements){
expandArray();
array[num_elements] = val;
}
else{
for(int i = 0;i<array_size;i++){
tempArr[i] = array[i];
}
tempArr[num_elements] = val;
array = tempArr;
}
num_elements++;
}
void IntVector::remove(int index){
}
int IntVector::get(int index) const{
return index;
}
void IntVector::removeLast(){
}
void IntVector::set(int index, int val){
}
std::string IntVector::toString()const {
return "";
}
IntVector::IntVector(int initial_size){
int* array = new int[initial_size];
}
IntVector:: ~IntVector(){
delete[] array;
}
int main(){
IntVector v(0);
v.add(5);
}
#ifndef INTVECTOR_H_
#define INTVECTOR_H_
using std::cout;
class IntVector {
private:
int* array;
int num_elements;
int array_size;
int expansion_factor;
void expandArray();
public:
void add(int val);
void remove(int index);
int get(int index) const;
void removeLast();
void set(int index, int val);
std::string toString() const;
IntVector(int initial_size);
~IntVector();
};
#endif
As mention in the comments, there are definitely some holes in your understanding of C++. Really when dealing with header files you should have a main.cpp, someotherfile.h, someotherfile.cpp. That just best practices to avoid redefinition errors.
There was quite a bit wrong with the way you accessed the private variable. If a class has a private( or even public) variable you don't have to redeclare it each time you want to change its value.
There were one or two major flaws with the way you expanded the vector. If the vector size is initialized to 0 then 0*2 is still 0 so you never actually increased the size. Secondly, when you set the original array = to the new array the new array was just a local array. This means that the memory wasn't actually allocated permanently, once the function ended the temparr was destroyed.
I know this was probably a lot but if you have any question feel free to ask.
main.cpp
#include "IntVector.h"
int main()
{
IntVector v;
IntVector x(10);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.push(5);
v.print();
cout << endl;
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.push(5);
x.print();
return 0;
}
IntVector.h
#include <string>
#include <iostream>
using namespace std;
class IntVector {
private:
int *array;
int num_elements;
int array_size;
//int expansion_factor =; you would only need this if you plan on more than double the vector size
void expandArray(); //normally c++ array double in size each time they expand
public:
//Constructors
IntVector(); //this is a contructor for if nothing is called
IntVector(int initial_size);
//setters
void push(int val); //add
void pop(); //removelast
void remove(int index); //remove
void at(int index, int val); //set
//Getters
int at(int index);
//std::string toString(); I'm changing this to print
void print(); //will print the contents to the terminal
//Deconstructor
~IntVector();
};
IntVector.cpp
#include "IntVector.h"
//constructors
IntVector::IntVector() //no arguments given
{
array = new int[0];
num_elements = 0;
array_size = 0;
}
IntVector::IntVector(int initial_size)
{
array = new int[initial_size];
num_elements = 0;
array_size = initial_size;
}
void IntVector::expandArray()
{
int *tempArr;
if(array_size == 0){
array_size = 1;
tempArr = new int[1];
} else {
//make sure to allocate new memory
//you were creating a local array which was destroy after the function was completed
//using new will allow the array to exist outside the function
tempArr = new int[array_size * 2];
}
for (int i = 0; i < array_size; i++)
{
tempArr[i] = array[i];
}
//make sure to delete the old array otherwise there is a memory leak.
//c++ doesn't have a garbage collector
delete[] array;
array = tempArr;
array_size = array_size * 2;
}
void IntVector::push(int val)
{
num_elements++;
//checking if vector needs to increase
if (array_size <= num_elements)
{
expandArray();
array[num_elements-1] = val;
}
else
{
array[num_elements-1] = val;
}
}
void IntVector::remove(int index)
{
//not sure how to implment this becuase each element has to be a number.
}
int IntVector::at(int index)
{
return array[index];
}
void IntVector::pop()
{
num_elements = num_elements-1; //not really removing it from the "vector" but it won't print out again
}
void IntVector::at(int index, int val)
{
array[index] = val;
}
void IntVector::print()
{
for (int i = 0 ; i < num_elements; i++)
{
cout << array[i] << " ";
}
cout << endl;
}
IntVector::~IntVector()
{
delete[] array;
}
output
5 5 5 5 5
5 5 5 5 5
Hopefully, the comments help. I changed the name of the functions to better match the actual vecter class the already exists in C++. I think it's good to pick apart already defined functions like this because you get a better understanding of how they actually work and not just how to use them.
If you got any questions just leave a comment

Setter not changing the data from a vector within a class

In my program, I have a class that holds a vector of type integer. It is used to store distances. I have a function, that when called, should set values in the vector to 0's. (used for initializing). But when I go to check the size of the vector, it still says the vector is empty.
I have created multiple functions that check whether the vector is adding any elements, and it is not. I have a function, that within main, I call to see if the vector is empty, and it returns 0 (the vector has 0 elements in it).
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
The input file is a csv file with each line consisting of:
stadium1,stadium2,distance
so sample input file is:
AT&T Park,Safeco Field,680
AT&T Park,Oakland–Alameda County Coliseum,50
Angel Stadium,Petco Park,110
Angel Stadium,Dodger Stadium,50
Busch Stadium,Minute Maid Park,680
Busch Stadium,Great American Ball Park,310
Busch Stadium,Target Field,465
Busch Stadium,Kauffman Stadium,235
etc...
I am using qt, and this is where I am calling the functions themselves. All information is stored into a map, and the other getters work perfectly fine. Sorry for making this a lot more confusing than the problem really is, any help is greatly appreciated.
// key and value, key is the team name, value is the MLB stadium information
struct entry
{
string key;
MLB value;
};
class Map
{
public:
//Public default constructor
Map();
//Public default destructor
~Map();
// returns entry of the map
entry atIndex(int index);
// Inserts a key and its value using linear algorithm
void insert(const string& theKey, const MLB& value);
private:
vector<entry> thisTable;
int currentSize; //Integer variable for current size
};
functions for Map:
Map::Map()
{
currentSize = 0;
}
Map::~Map()
{
}
void Map::insert(const string& theKey, const MLB& value)
{
entry thisEntry;
thisEntry.key = theKey;
thisEntry.value = value;
thisTable.push_back(thisEntry);
currentSize+=1;
}
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
//mainwindow constructor
mainWindow::mainWindow()
{
//Reads in input from first csv file, all works fine all data stored and can access it
string iStadium1;
string iStadium2;
string iDistance;
string previous;
int distance;
int index1;
int index2;
bool found;
ifstream csvFile2;
csvFile2.open("inputDistance.csv");
getline(csvFile2, iStadium1, ',');
while(!csvFile2.eof())
{
index1 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index1).value.getStadiumName() == iStadium1)
{
thisMap.atIndex(index1).value.setInitialDistances(thisMap.mapSize());
cout << "Distance Size Test 1: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
found = true;
}
else
{
index1++;
}
}
previous = iStadium1;
while(iStadium1 == previous)
{
getline(csvFile2, iStadium2, ',');
getline(csvFile2, iDistance, '\n');
distance = stoi(iDistance);
index2 = 0;
found = false;
while(!found)
{
if(thisMap.atIndex(index2).value.getStadiumName() == iStadium2)
{
found = true;
cout << "Distance Size Test 2: " << thisMap.atIndex(index1).value.getDistanceSize() << endl;
// crashes here. Index out of bounds, size is 0 for some reason
thisMap.atIndex(index1).value.setDistance(index2, distance);
}
else
{
index2++;
}
}
getline(csvFile2, iStadium1, ',');
}
}
csvFile2.close();
}
I expect the vector to hold 30 slots (assuming the desired size passed into the function is 30) of value 0, rather than having an empty vector.
The code in your question works as expected after adding constructor and destructor (doing both nothing) :
#include <iostream>
#include <vector>
using namespace std;
class MLB
{
public:
//constructor
MLB();
~MLB();
int getDistanceSize();
void setInitialDistances(int size);
private:
vector<int> distances;
};
int MLB::getDistanceSize()
{
return distances.size();
}
void MLB::setInitialDistances(int size)
{
for(int i = 0; i < size; i++)
{
this->distances.push_back(0);
}
}
MLB::MLB() {
}
MLB::~MLB() {
}
int main()
{
MLB mlb;
mlb.setInitialDistances(30);
cout << mlb.getDistanceSize() << endl;
}
pi#raspberrypi:/tmp $ g++ d.cc
pi#raspberrypi:/tmp $ ./a.out
30
the vector is not empty but contains 30 times 0
if thisMap.atIndex(index1).value.setDistance(index2, distance); does nothing this is probably because atIndex(index1) returns a copy rather than a reference, so you modify a copy and the original is unchanged
For instance :
#include <iostream>
#include <vector>
using namespace std;
class C {
public:
vector<int> getv() { return v; } // return a copy
vector<int> & getvref() { return v; } // return the ref to the vector, not a copy
int len() { return v.size(); }
private:
vector<int> v;
};
int main()
{
C c;
c.getv().push_back(0); // modify a copy of v
cout << c.len() << endl;
c.getvref().push_back(0); // modify v
cout << c.len() << endl;
}
Compilation and execution :
pi#raspberrypi:/tmp $ g++ vv.cc
pi#raspberrypi:/tmp $ ./a.out
0
1
you edited you question and this is what I supposed :
entry Map::atIndex(int index)
{
return thisTable.at(index);
}
return a copy, must be
entry & Map::atIndex(int index)
{
return thisTable.at(index);
}

What is right way to access elements of std::array by passing as a pointer to function in C++?

The code snippet is as follows. The error is in foo function for the cout line:
typedef struct Datatype {
int first;
int second;
} Datatype;
void foo(std::array<Datatype, 100>* integerarray){
cout << *integerarray[0].first << endl; //ERROR: has no member first
}
void main() {
std::array<Datatype, 100> newarray;
for(int i=0; i<100; i++)
newarray[i] = i;
}
foo(&newarray);
}
Because of operator precedence, *integerarray[0].first is translated as *(integerarray[0].first), which is not what you want. You need to use (*integerarray)[0].first.
cout << (*integerarray)[0].first << endl;
You can make your life simpler by passing a reference.
void foo(std::array<Datatype, 100>& integerarray){
cout << integerarray[0].first << endl;
}
Also, you don't need to use typedef struct DataType { ... } DataType; in C++. You can use just struct DataType { ... };
newarray[i] = i;
In this line you have missed adding value to structure variables.
Also you have passed array as a reference to function. Removing it and passing just the name of array will pass base address of array.
I am adding following code for your reference:
#include<iostream>
#include <array>
struct Datatype{
int first;
int second;
}
typedef Datatype varInts;
void display(std::array<varInts,20> &dummy)
{
int b =5;
for(int i=0; i<20; i++)
{
dummy[i].first =b++;
dummy[i].second = b+5; //Give any logic you wish.just adding different values;
b++;
}
}
int main()
{
std::array<varInts,20> data;
int a =1;
for(int i=0;i<20;i++)
{
data[i].first = a++;
data[i].second = a+5;
a++; //Just adding values for example
}
display(data);
return 0;
}
It runs without error.Hope it helps!!

C++ Vectors in a Class

i am working on a worksheet i have for university and the question asks me to "Allow a user to enter 10 numbers from the keyboard into an array" however we have been told that we need to use classes and vectors for this task. When i run my code i get an error stating: "Expression: Vector subscript out of range"
can anyone help?
Array.h
#include <iostream>
#include <vector>
using namespace std;
class Array
{
private:
vector<int> lists;
public:
void fillArray();
void printForwards();
void halfandHalf();
void shiftArrayRight();
Array();
Array(vector<int>);
};
Array.cpp
#include "Array.h"
Array::Array()
{
lists[10];
}
Array::Array(vector<int> lists)
{
this->lists = lists;
}
void Array::fillArray()
{
for (int i = 0; i < 10; i++)
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < 10; i++)
{
cout << lists[i];
}
}
Source.cpp
#include <iostream>
#include "Array.h"
using namespace std;
int main()
{
Array list1,list2;
//fill array 1
list1.fillArray();
//fill array 2
list2.fillArray();
// print array 1
list1.printForwards();
//print array 2
list2.printForwards();
system("pause");
return 0;
}
Thanks in advance
lists[10]; is not going to create a vector of size 10. It is going to try and access the 11th element of an empty vector. If you wanted to create a vector of size 10 then you can use
Array::Array() : lists(std::vector<int>(10, 0)) {}
I would also suggest you change
Array::Array(vector<int> lists)
{
this->lists = lists;
}
To
Array::Array(vector<int> lists) lists(lists) {}
You should also change your for loops to use the vector size() instead of a hard coded value
void Array::fillArray()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cin >> lists[i];
}
}
void Array::printForwards()
{
for (int i = 0; i < lists.size(); i++) // uses size()
{
cout << lists[i];
}
}
Or if you have C++11 or higher you can use a ranged based for loop like
void Array::fillArray()
{
for (auto& e : lists)
{
cin >> e;
}
}
void Array::printForwards()
{
for (const auto& e : lists)
{
cout << e;
}
}

Unresolved overloaded type>[int] for array subscript c++

I'm getting the error message 'Unresolved overloaded type>[int] for array subscript' in my flight-booking-system program.
What I'm trying to do is set it so that if [j] is equal to 0,1,2,3... it will display accordingly as A,B,C,D. Until I started doing this my program at least compiled。
// Flight Class - Scotia 2
//
// Contains information on seating (array), space available and return to menu option.
#include <iostream>
#include <string>
#include "passenger.h"
#include "Seat.h"
using namespace std;
/*struct Seat
{
int Available;
std::string fullName;
};// End of struct*/
class Flight
{
public:
//default constructor
Flight()
{
//initialise all seat numbers
for(int i=0;i<4;i++)
for(int j=0;j<6;j++)
{// assigns seats as 1A, 1B etc...
seatPlan[i][j].setRow(row);
if(j==0)
seatPlan[i][j].setCol('A');
else if(j==1)
seatPlan[i][j].setCol('B');
else if(j==2)
seatPlan[i][j].setCol('C');
else if(j==3)
seatPlan[i][j].setCol('D');
}
}
Seat seatArray[4][6];
void seatPlan()
{
for (int ROW=0;ROW<4;ROW++)
{
for (int COL=0;COL<6;COL++)
{
cout << seatPlan[i][j].getSeatRow();
}
}
// End of for loop
}// End of seatPlan function
//method which returns true if seat is Available and false otherwise
bool getAvailable(int i, int j)
{
if(seatArray[i][j].Available == 0)
return true; //seat available
else
return false; //seat occupuied
}
string getName(int i,int j){return seatArray[i][j].fullName;}
void setAvailable(int i, int j, int a){seatArray[i][j].Available = a;}
void setName(int i,int j, string name){seatArray[i][j].fullName = name;}
private:
//variables
int row;
char col;
};// End of Flight class
The above is my flight.h file which contains the Flight class. The error message points to my constructor, with the message repeating for all the lines within that contain seatPlan[i][j].setCol('A'); and so on.
I'll include the 'seat.h' file also, just in case it's relevant.
#ifndef SEAT
#define SEAT
#include <iostream>
using namespace std;
class Seat
{
public:
//deafult constructor
Seat(){available = true;}
//accessor methods
void setRow(int row){seatRow = row;}
void setCol(char col){seatCol = col;}
int getSeatRow(){return seatRow;}
char getSeatCol(){return seatCol;}
bool isAvailable(){return available;}
bool switchAvailable(){
if(available)
available = false;
else
available = true;
}
private:
bool available;
int seatRow;
char seatCol;
};
#endif
seatPlan[i][j].setRow(row);
Here is the problem. seatPlan is not an array. It is the name of the function.
You meant seatArray. So it should be:
seatArray[i][j].setRow(row);
One suggestion: consider using std::array as:
std::array<std::array<Seat,6>,4> seatArray;
instead of
Seat seatArray[4][6];
void seatPlan() is a method and you're treating it as an array. Did you mean seatArray instead?
Also
if(seatArray[i][j].Available == 0)
return true; //seat available
else
return false; //seat occupuied
? Really? Why not just
return seatArray[i][j].Available == 0;
(assuming you fix the previous error)