throw not working properly - c++

I declared the size of the array to be 2 and I tried inserting on the 3rd array position. The insert function is supposed to throw -1 when the position > size+1(using pos-1 when assigning the element into the array) but the throw is not stopping the assignment for the 3rd array position so I am getting a segmentation fault.
template <class T, int N>
class person : public people<T>
{
private:
T a[N];
int size;
public:
person();
virtual void insert(int pos, T info);
virtual T show(int pos);
};
template<class T, int N>
person<T,N>::person(){
size = 0;
}
template <class T, int N>
void person<T,N>::insert(int pos, T info){
if (pos <= 0 || pos > size+1)
throw -1;
a[pos-1] = info;
++size;
}
template <class T, int N>
T person<T,N>::show(int pos){
if ( pos <= 0 || pos > size+1 )
throw -1;
return a[pos-1];
}
void putin( people<name>*& aPerson ) {//passing aPerson itself
string first("Julia"), last("Robert");
name temp(first, last);
string ft("Delilah"), lt("McLuvin");
name temp2(ft, lt);
string fst("oooh lala"), lst("broomdat");
name temp3(fst, lst);
try{
aPerson-> insert(1,temp);
aPerson-> insert(2,temp2);
aPerson-> insert(3,temp3);
}
catch(...){ cout<< "error\n";}
}
int main(){
people<name>* aPerson = new person<name, 2>();
putin(aPerson);
try{
cout << aPerson->show(1);
cout << aPerson->show(2);
cout << aPerson->show(3);
}
catch(...){ cout<< "error\n";}
return 0;
}

Every time you insert something, you check size variable and later increment it. When you hit size == N, nothing happens. You just step out of array bounds, you need to consider case when size is about to get bigger than your array.

Are you using STL? If yes better try using vector<T>::at secure method which will do all necessary checks for you and throw std::out_of_range exception when getting outside its bounds.

Related

ERROR: What does "use of class template 's_array' requires template arguments" mean?

Im currently studying for an exam in c++.
I'm doing some practice questions on templates and have became totally stuck, i'v checked my code and it follows the solutions but this error keeps poping up. I'm unsure how I am passing in the wrong arguements (this is what I believe the issue is.
Code is listed below, any help is greatly appreciated
Tester
int main(){
s_array array(10);
array[5] = 5; //inbound access
cout << array[5] << endl;
array[-1] = 2;
cout << array[15];
return 0;
}
header, class and templates:
template <typename T>
class s_array {
public:
s_array(int size);
~s_array();
T &operator[](int i);
private:
int size;
T* data;
};
template <typename T>
s_array<T>::s_array(int size) : size(size)
{
/*
* If the size of the array is greater than zero
* A new array is created at the value of size
*/
if(size > 0) data = new T[size];
else{
std::cout << "Invalid array" << endl;
exit(1);
}
}
template <typename T>
s_array<T>::~s_array()
{
delete [] data;
}
/*
* Safety feature for the array going out of bounds
*/
template <typename T>
T& s_array<T>::operator[](int i)
{
if(i < 0 || i >= size){
std::cout << "index" << i << "is out of bounds" << endl;
exit(1);
}
return data[i];
}
You need to say what type the s_array is holding, for example this would define the array to contain int types. In the template definition, int will now be substituted everywhere that T used to be
s_array<int> array(10);

Segmentation Fault when Overloading addition operator and dynamic vectors

I'm trying to overload the addition operator but I keep getting a segmentation fault even though I'm passing in the argument by value after it's memory has been deallocated. Anybody have any idea what I could be doing wrong. Also once I get this running properly after fixing the overloaded addition, I need to use vectors instead of pointing to arrays which I have no idea how to declare in a manner equivalent to what I've wrritten for arrays.
RowAray.h
#ifndef ROWARAY_H // if constant ROWARAY_H not defined do not execute
#define ROWARAY_H // defines constant ROWARAY_H
#include <new> // Needed for bad_alloc exception
#include <cstdlib> // Needed for the exit function
template <class T>
class RowAray{
private:
int size;
T *rowData;
void memError(); // Handles memory allocation errors
void subError(); // Handles subscripts out of range
public:
RowAray(T); //used to construct row Array object
~RowAray(){delete [] rowData;} //used to deallocate dynamically allocated memory from Row array
int getSize(){return size;} //inline accessor member function used to return length of Row array
void setData(int row, T value);
T getData(int i){return (( i >=0&& i < size)?rowData[i]:0);} //
T &operator[](const int &);
};
template <class T>
RowAray<T>::RowAray(T colSize){
size =colSize>1?colSize:1;
// Allocate memory for the array.
try
{
rowData = new T [size];
}
catch (bad_alloc)
{
memError();
}
// Initialize the array.
for (int count = 0; count < size; count++){
T value = rand()%90+10;
setData(count, value);
}
}
template <class T>
void RowAray<T>::memError()
{
cout << "ERROR:Cannot allocate memory.\n";
exit(EXIT_FAILURE);
}
template <class T>
void RowAray<T>::subError()
{
cout << "ERROR: Subscript out of range.\n";
exit(EXIT_FAILURE);
}
template <class T>
T &RowAray<T>::operator[](const int &sub)
{
if (sub < 0 || sub >= size)
subError();
else
return rowData[sub];
}
template <class T>
void RowAray<T>::setData(int row, T value){
//used to fill array with random 2 digit #s
*(rowData + row) = value;
}
#endif /* ROWARAY_H */
Table.h
#ifndef TABLE_H
#define TABLE_H
#include "RowAray.h"
template <class T>
class Table{
private:
int szRow;
int szCol;
RowAray<T> **records;
public:
Table(int,int); //used to construct Table object
Table(const Table &);
~Table(); //used to deallocate dynamically allocated memory from Table object
int getSzRow() const{return szRow;} //used to return row size
int getSzCol()const {return szCol;}
Table operator+(const Table &);
T getRec(int, int) const; //used to return inserted random numbers of 2d arrays
};
template <class T>
Table<T>::Table(int r, int c ){
//Set the row size
this->szRow = r;
//Declare the record array
records = new RowAray<T>*[this->szRow];
//Size each row
this->szCol = c;
//Create the record arrays
for(int i=0;i<this->szRow;i++){
records[i]=new RowAray<T>(this->szCol);
}
}
template <class T>
Table<T>::Table(const Table &Tab){
szRow=Tab.getSzRow();
szCol=Tab.getSzCol();
records = new RowAray<T>*[szCol];
for(int i = 0; i < this->szCol; i++){
records[i] = new RowAray<T>(szRow);
}
//set elements = to random value
for(int row = 0; row < szRow; row++){
for(int col = 0; col < this->szCol; col++){
int value = Tab.getRec(row, col);
records[col]->setData(row,value);
}
}
}
template <class T>
T Table<T>::getRec(int row, int col) const{
//if else statement used to return randomly generated numbers of array
if(row >= 0 && row < this->szRow && col >= 0 && col < this->szCol){
return records[row]->getData(row);
}else{
return 0;
}
}
template <class T>
Table<T>::~Table(){
//Delete each record
for(int i=0;i<this->szRow;i++){
delete records[i];
}
delete []records;
}
template <class T>
Table<T> Table<T>::operator+(const Table &Tab){
Table temp(Tab.getSzRow(), Tab.getSzCol());
//set elements = to random value for operation to
for(int row=0; row < szRow; row++){
for(int col=0; col < szCol; col++){
int value = getRec(row, col) + Tab.getRec(row, col);
temp.records[col]->setData(row,value);
}
}
return temp;
}
#endif /* TABLE_H */
main.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
//User Libraries
#include "Table.h"
//Global Constants
//Function Prototype
template<class T>
void prntRow(T *,int);
template<class T>
void prntTab(const Table<T> &);
//Execution Begins Here!
int main(int argc, char** argv) {
//Initialize the random seed
srand(static_cast<unsigned int>(time(0)));
//Declare Variables
int rows=3,cols=4;
//Test out the Row with integers and floats
RowAray<int> a(3);
RowAray<float> b(4);
cout<<"Test the Integer Row "<<endl;
prntRow(&a,3);
cout<<"Test the Float Row "<<endl;
prntRow(&b,4);
//Test out the Table with a float
Table<float> tab1(rows,cols);
Table<float> tab2(tab1);
Table<float> tab3 = tab1 + tab2;
cout<<"Float Table 3 size is [row,col] = Table 1 + Table 2 ["
<<rows<<","<<cols<<"]";
prntTab(tab3);
//Exit Stage Right
return 0;
}
template<class T>
void prntRow(T *a,int perLine){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int i=0;i<a->getSize();i++){
cout<<a->getData(i)<<" ";
if(i%perLine==(perLine-1))cout<<endl;
}
cout<<endl;
}
template<class T>
void prntTab(const Table<T> &a){
cout<<fixed<<setprecision(1)<<showpoint<<endl;
for(int row=0;row<a.getSzRow();row++){
for(int col=0;col<a.getSzCol();col++){
cout<<setw(8)<<a.getRec(row,col);
}
cout<<endl;
}
cout<<endl;
}
You error stems from line 85 of Table.h, in you + operator overload:
temp.records[col]->setData(row,value);
should really be
temp.records[row]->setData(col,value);
Apart from that, I spotted another error in the same file in line 62 (method Table<T>::getRec(int row, int col)):
return records[row]->getData(row);
should be
return records[row]->getData(col);
Apart from those problems, I would highly advise you to rethink and restructure your code (maybe you could also try a code review), since a large part of it is superfluous in my opinion and some things could become problematic if you expand the project (for example, RowAray's constructor takes a T colSize as parameter where you should probably use an int or, better, a size_t. This code as it is will not work when T is not implicitly convertible to an integer type).

Super basic hash table set-up memory allocation errors

Yes I am still learning C++ and I am trying to create my own Hash.h header with several hash functions (non-cryptic) such as MurmurHash and CityHash. To start this off I just wanted a very basic implementation first. But it is not compiling as I have some memory errors. It is due to adding a entry where data is passed to the class function. Changing to pointers/references gave similar errors and I just can't seem to fix it. Can somebody see what is going wrong such that I know what to look for in the future? Thanks!
//Hash.h
template<class T>
class HashEntry{
private:
int key;
T data;
public:
HashEntry() {};
void putData(T input, int keyVal){
//SEGMENTATION FAULT HAPPENS HERE!!
key = keyVal;
data = input;
}
T getData(){
return data;
}
};
template<class T>
class Hash{
private:
int myFunc;
size_t sizeHash;
HashEntry<T> **table;
public:
Hash(int func, size_t size): myFunc(func), sizeHash(size-1) {
table = new HashEntry<T>*[sizeHash];
for (int i=0;i<sizeHash;i++) table[i] = NULL;
}
int hashFunc(int key){
try{
if (myFunc == 0){
return key % sizeHash;
} else if (myFunc == 1){
//other has func's
} else {string excep = "No such hash function!"; throw excep;}
} catch(string e) {cout << "Hash::hashFunc(): Exception Raised: " << e << endl; exit(0);}
return -1;
}
void addEntry(T data, int key){
int myHash = hashFunc(key);
table[myHash]->putData(data, key);
}
};
Call from main:
Hash<char> *myHash = new Hash<char>(0,10);
myHash->addEntry('s', 11);
return 0;

Use of pointers in a stack class?

I'm learning C++, and we were given an exercise to make a stack class using a class template and pointers. I'm not yet fully understanding the implementation of a stack or pointers so I gave it a go and made this class:
template <class T>
class Stack_Class {
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value) {
if (value > 0) {
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class() {
if (First_item) {
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num) {
if (item_quantity <Max_quantity) {
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop() {
if (!Empty()) {
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty() {
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity() {
return Max_quantity;
}
And the main class would be:
#include <iostream>
#include "Stack_Class.h"
void main() {
Stack_Class<int> intStack(3);
intStack.Add(1);
intStack.Add(2);
intStack.Add(3);
int count = intStack.GetMax_Quantity();
for (int i = 0; i < count; i++) {
std::cout << "Pop No: " << i << " - Elemento: " << intStack.Pop() << std::endl;
}
}
Though as a result I'm getting all random numbers instead of the ones I gave it in intStack. Add, so my question would be I'm implementing the pointer correctly here?
You need to deincrement the stack pointer before you reference it within Pop():
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
stack--;
return *stack;
}
return NULL;
}
Your array access stack[item_quantity] does not work because you increment stack in Add. So after construction, the memory pointed to by stack looks like this
0xff65f96f <-- *(stack + 0)
0x0eec604f <-- *(stack + 1)
0x05be0582 <-- *(stack + 2)
0x29b9186e <-- *(stack + 3)
The hexdecimal values represent random garbage coincidentely located in the memory at the time of allocation. This is because memory allocated by new is not initialized to something nice. After adding three values, it looks like this
1 <-- *(stack - 3)
2 <-- *(stack - 2)
3 <-- *(stack - 1)
0x29b9186e <-- *(stack + 0)
0xf66eff06 <-- *(stack + 1)
0x357eb508 <-- *(stack + 2)
In the first call of Pop, you access stack[2] = *(stack + 2), because item_quantity is 2 after deincrementing it. The two consecutive calls to Pop access stack[1] and stack[0]. As you can see above, you never actually reference the values you’ve put into the stack.
You are mixing up the pointer incrementing semantic in the Add method and the indexing semantic in the Pop method.
Since you need the index for the Empty method and so on, I would fix your Add method instead of the Pop as can be seen below.
Otherwise, you would end up still using the indexing in some method(s), but not in other. It would not look consistent to me.
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
stack[item_quantity++] = num;
return true;
}
else return false;
}
Yet another problem in your code is this:
stack = new T[value];
but you seem to only delete the first element in the pointer. That is a guaranteed (and potentially not negligible) memory leak.
Even if you fix all that, your code would not still compile since you are trying to return void, whereas a C++ program should return int, so change this:
void main(){
...
}
to:
int main(){
...
}
... and return an integer like 0 correspondingly.
You would also need to fix this warning:
Stack_Class.h:56:13: warning: converting to non-pointer type ‘int’ from NULL [-Wconversion-null]
return NULL;
^
By for instance change NULL to 0.
Having fixed all that, the output is like this:
Pop No: 0 - Elemento: 3
Pop No: 1 - Elemento: 2
Pop No: 2 - Elemento: 1
You can also see the code running on ideone.
For your convenience, this is the whole working code after those fixes:
template <class T>
class Stack_Class{
public:
T* stack;
int item_quantity;
T* First_item;
int Max_quantity;
Stack_Class(int value);
~Stack_Class();
bool Add(T value);
T Pop();
int GetMax_Quantity();
bool Full();
bool Empty();
};
template <class T>
Stack_Class<T>::Stack_Class(int value){
if (value > 0){
stack = new T[value];
First_item = stack;
item_quantity = 0;
Max_quantity = value;
}
}
template <class T>
Stack_Class<T>::~Stack_Class(){
if (First_item){
delete First_item;
}
}
template<class T>
bool Stack_Class<T>::Add(T num){
if (item_quantity <Max_quantity){
*stack = num;
stack++;
item_quantity++;
return true;
}
else return false;
}
template<class T>
T Stack_Class<T>::Pop(){
if (!Empty()){
item_quantity--;
return stack[item_quantity];
}
return NULL;
}
template<class T>
bool Stack_Class<T>::Empty(){
return (item_quantity == 0);
}
template <class T>
int Stack_Class<T>::GetMax_Quantity(){
return Max_quantity;
}

Errors with a Template in C++ regarding operators

In my project, I am using a header file for an arrayList. During the main method, I initialize an object of type arrayList where FriendToken is another class defined in my project. However, this gives me quite a few errors while compiling arrayList.h. Apparently, I cannot use the built-in copy method and the operator == is unrecognized for an object of type FriendToken. Should I overload the == operator for FriendToken and if so, how should I do that?
Both errors are marked in the body ArrayList.h.
ArrayList.h:
#ifndef arrayList_h
#define arrayList_h
#include "linearList.h"
#include <iostream>
#include <fstream>
#include <ostream>
using namespace std;
template<class T>
class arrayList : public linearList<T>
{
public:
// constructor, copy constructor and destructor
arrayList(int initialCapacity = 10);
arrayList(const arrayList<T>&);
~arrayList() {delete [] element;}
// ADT methods
bool empty() const {return listSize == 0;}
int size() const {return listSize;}
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(ostream& out) const;
void changeLength1D(T*& a, int oldLength, int newLength);
// additional method
int capacity() const {return arrayLength;}
protected:
void checkIndex(int theIndex) const;
// throw illegalIndex if theIndex invalid
T* element; // 1D array to hold list elements
int arrayLength; // capacity of the 1D array
int listSize; // number of elements in list
};
template<class T>
arrayList<T>::arrayList(int initialCapacity)
{
// Constructor.
arrayLength = initialCapacity;
element = new T[arrayLength];
listSize = 0;
}
template<class T>
arrayList<T>::arrayList(const arrayList<T>& theList)
{
// Copy constructor.
arrayLength = theList.arrayLength;
listSize = theList.listSize;
element = new T[arrayLength];
copy(theList.element, theList.element + listSize, element);
}
template<class T>
void arrayList<T>::checkIndex(int theIndex) const
{
// Verify that theIndex is between 0 and
// listSize - 1.
if (theIndex < 0 || theIndex >= listSize)
{
cout << "index = " << theIndex << " size = "
<< listSize;
}
}
template<class T>
T& arrayList<T>::get(int theIndex) const
{
// Return element whose index is theIndex.
// Throw illegalIndex exception if no such
// element.
checkIndex(theIndex);
return element[theIndex];
}
template<class T>
int arrayList<T>::indexOf(const T& theElement)const
{
// Return index of first occurrence of theElement.
// search for theElement
int theIndex = (int) (find(element, element
+ listSize, theElement) - element);
// check if theElement was found
if (theIndex == listSize)
return -1; // not found
else return theIndex;
}
template<class T>
void arrayList<T>::erase(int theIndex)
{// Delete the element whose index is theIndex.
checkIndex(theIndex);
// valid index, shift elements with higher index
//PROBLEM********************************************
copy(element + theIndex + 1, element + listSize,element + theIndex);
element[--listSize].~T(); // invoke destructor
}
template<class T>
void arrayList<T>::insert(int theIndex, const T& theElement)
{
// Insert theElement.
if (theIndex < 0 || theIndex > listSize)
{// invalid index
// code to throw an exception comes here
}
// valid index, make sure we have space
if (listSize == arrayLength)
{
// no space, double capacity
changeLength1D(element, arrayLength,
2 * arrayLength);
arrayLength *= 2;
}
// shift elements right one position
//PROBLEM***************************************
copy_backward(element + theIndex, element + listSize, element + listSize + 1);
element[theIndex] = theElement;
listSize++;
}
template<class T>
void arrayList<T>::output(ostream& out) const
{
// Put the list into the stream out.
copy(element, element + listSize, ostream_iterator<T>(out, " "));
}
template <class T>
ostream& operator<<(ostream& out, const arrayList<T>& x)
{x.output(out); return out;}
template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
if (newLength < 0)
throw illegalParameterValue();
T* temp = new T[newLength];
// new array
int number = min(oldLength, newLength);
// number to copy
copy(a, a + number, temp);
delete [] a;
// deallocate old memory
a = temp;
}
#endif
FriendToken.h
#ifndef FriendToken_h
#define FriendToken_h
#include <string>
using namespace std;
class FriendToken
{
private:
string birthDate, name, homeTown;
public:
FriendToken(string birthDate = "01/01", string name = "John, Smith", string homeTown = "New York");
string getBirthDate();
string getName();
string getHomeTown();
bool equals(FriendToken a);
};
#endif
FriendToken.cpp
#include "FriendToken.h"
#include <string>
using namespace std;
FriendToken::FriendToken(string birthDate, string name, string homeTown)
{
this->birthDate = birthDate;
this->name = name;
this->homeTown = homeTown;
}
string FriendToken::getBirthDate()
{
return birthDate;
}
string FriendToken:: getName()
{
return name;
}
string FriendToken::getHomeTown()
{
return homeTown;
}
bool FriendToken::equals(FriendToken a)
{
return (name == a.getName()) && (homeTown == a.getHomeTown()) && (birthDate == a.getBirthDate());
}
It's hard to tell without the compiler errors.
Either way, this is how you overload the operator.
template<typename T>
bool arrayList::operator== (const arrayList<T>& theList)
{
// Compare the values, and return a bool result.
}