Classes misunderstanding and bad_alloc error or bad initialization? - c++

I am trying to read some values remember them in object dep, and then show them. It shows random values and crashes. Can you tell me what is wrong in my program, it shoul be something about allocation..
#include<iostream>
)
{
std::cout<
and those are Wagon.h and Stack.h
template <typename T>
class Stack
{
T *stackArray;
....
Stack();
~Stack();
void push( T x );
void show();
void add(int M);
};
template <typename T>
Stack<T>::Stack()
{
stackArray = NULL;
topLevel = 0;
}
template <typename T>
Stack<T>::~Stack()
{
if ( stackArray != NULL )
delete [] stackArray;
}
void Wagon::printId()
{
std::cout<<id<<" ";
}
and main:
dep.addVagL(0,9);
dep.showDepot(2,2);

You can begin fixing your code by allocating the lines array in the Depot constructor:
Depot::Depot(int N, int M)
{
lines = new Stack<Wagon>[N];
for (int i=0; i<N; i++)
{
lines[i].add(M);
}
}

Related

C++ Memory leakage with Dynamic Arrays

I had to build a dynamic array class from scratch myself, and I also tried to extend it with a (set like) function to add new elements into the array, it compiles well, but the program crashes, since it has some memory leakages.
Please try and help me, I'm on a short notice at school.
The array class
template <class T>
class Array
{
int n; /// size
T* data;
public:
explicit Array(int n): n(n) { adat=new T[n]; }
Array(const Array&);
Array& operator=(const Array&);
~Array();
T& operator[](int idx) { return data[idx]; }
int size() { return n; }
int lookfor(T);
void add(T);
void del();
};
DEFINITIONS
template <class T>
Array<T>::Array(const Array<T>& t)
{
n=t.n;
data=new T[n];
for (int idx=0; idx<n; ++idx)
data[idx]=t.data[idx];
}
/**
Operator=
*/
template <class T>
Array<T>& Array<T>::operator=(const Array<T>& t)
{
if (this==&t) return *this;
delete[] data;
n=t.n;
data=new T[n];
for (int idx = 0; idx < n; ++idx)
data[idx]=t.data[idx];
return *this;
}
/**
dtor
*/
template <class T>
Array<T>::~Array()
{
del();
}
This must be the wrong part
template <class T>
int Array<T>::lookfor(T el)
{
for(int idx = 0; idx < n; ++idx)
if(data[idx] == el)
return idx;
return -1;
}
/**
add
*/
template <class T>
void Array<T>::add(T el)
{
if(lookfor(elem) != -1)
{
T* temp = new T[n + 1];
for (int idx = 0; idx < n; ++idx)
temp[idx]=data[idx];
temp[n + 1] = el;
del();
data = temp;
++n;
}
}
template <class T>
void Array<T>::del()
{
for(int idx = 0; idx < n; ++idx)
delete data[idx];
delete[] data;
}
The code it fails with:
Control ctrl;
ctrl.add(new Room());
ctrl.add(new Room());
Control and Room are both subclasses of the array. Like Control : publicArray < Room* >
Get rid of the loop in del() that deletes all the data[idx] elements. data is not an array of pointers, it's an array of values of type T, so you can't delete them. Even if you make an array of pointers, these pointers came from the caller to add, and they're owned by that part of the program, not the Array class. You also don't want to delete all the old pointers when you add an element to the array, because the new data array still contains those pointers.
Calling delete on something that wasn't created using new results in undefined behavior, which is likely causing your crash.

Using variables from parent class

I've been trying to use template to implement stack. And my question is how do I use the variables from the parent class in this situation?
In this case my compile error is: 'top, a, size' was not declared in this scope.
template<class T>
class buffer
{
public:
T *a;
int top,i,size;
};
template<class T>
class Queue: public buffer<T>
{
public:
Queue(int siz)
{
a=new T[siz];
size=siz;
top=-1;
}
void push(T ele)
{
if(top!=size-1){a[++top]=ele;}
}
T pop()
{
return(a[top--]);
}
void print()
{
for(i=0;i<top;i++)
cout<<" "<<a[i];
cout<<endl;
}
};
To make them dependent name, you have to use this-> or buffer<T>:: before.
so
this->a = new T[siz];
this->size = siz;
this->top = -1;

Apple mach-o linker (id) error with C++

I created a new project in Xcode 5.0 to implement a Queue class as following:
I created a .h file called QueueArray.h and it contains the following:
#ifndef __Queue__QueueArray__
#define __Queue__QueueArray__
#include <iostream>
template <class T>
class QueueArray
{
public:
QueueArray(int cap);
~QueueArray();
void Enqueue(T& val);
T Dequeue(void);
T GetFirst(void);
T GetLast(void);
bool IsEmpty(void);
bool IsFull(void);
void Clear(void);
private:
T* data;
int capacity, size, first, last;
};
#endif
and a .cpp file called QueueArray.cpp that contains the following:
#include "QueueArray.h"
using namespace std;
template <class T>
QueueArray<T>::QueueArray(int cap)
{
capacity = cap;
data = new T[capacity];
size = 0;
first = last = -1;
}
template <class T>
QueueArray<T>::~QueueArray(void)
{
delete [] data;
}
template <class T>
void QueueArray<T>::Enqueue(T& el)
{
if(IsFull() == true)
{
printf("\n Can't enqueue into a full queue!");
return;
}
if(IsEmpty() == true)
first = last = 0;
else if(last == capacity-1)//if at the last entry
last = 0; //wrap around to the first entry
else
last++;
data[last] = el;
size++;
}
template <class T>
T QueueArray<T>::Dequeue()
{
if(IsEmpty() == true)
{
printf("\n Can't dequeue from an empty queue!");
return -1;
}
T el = data[first];
if(first == last) //if only one element in queue
last = first = -1; //we'll get an empty queue
else if(first == capacity-1) //if at the last entry
first = 0; //wrap around to the first entry
else //normal case
first++;
size--;
return el;
}
template <class T>
T QueueArray<T>::GetFirst()
{
return data[first];
}
template <class T>
T QueueArray<T>::GetLast()
{
return data[last];
}
template <class T>
bool QueueArray<T>::IsEmpty(void)
{
return size == 0;
}
template <class T>
bool QueueArray<T>::IsFull(void)
{
return size == capacity;
}
and a main.cpp file that contains the following:
#include <iostream>
#include "QueueArray.h"
using namespace std;
int main(int argc, const char * argv[])
{
QueueArray<int> q(100);
for (int i=0; i<100; i++)
{
q.Enqueue(i);
}
for (int i=0; i<100; i++) {
cout<<q.Dequeue()<<endl;
}
return 0;
}
When I try to run the project, a message appears saying "Build Failed" and here is a screenshot of the errors:
How to fix that?
The compiler needs to see the definition of the Template before using it.
http://www.parashift.com/c++-faq-lite/templates-defn-vs-decl.html
There are more than one solution:
a. Move the definitions from .cpp file to the .h file
b. Use the export keyword if your compiler supports
http://www.parashift.com/c++-faq-lite/separate-template-fn-defn-from-decl-export-keyword.html
c. Add an inline declaration:
http://www.parashift.com/c++-faq-lite/separate-template-fn-defn-from-decl.html
You need to include the template definitions in-line with their declarations. An easy solution to this is to rename QueueArray.cpp to something like QueueArray_impl.h and #include it from the bottom of QueueArray.h
#ifndef __Queue__QueueArray__
#define __Queue__QueueArray__
#include <iostream>
template <class T>
class QueueArray
{
public:
QueueArray(int cap);
~QueueArray();
void Enqueue(T& val);
T Dequeue(void);
T GetFirst(void);
T GetLast(void);
bool IsEmpty(void);
bool IsFull(void);
void Clear(void);
private:
T* data;
int capacity, size, first, last;
};
#include "QueueArray_impl.h"
#endif

c2955 Error - Use of Class template reuires argument list

So, I've tested vector and it seems to be running fine. However, I'm trying to implement a basic Stack class built off of my Vector class. I keep running into these errors when I go to build:
stack.h(4): error C2955: 'Vector' : use of class template requires template argument list
followed by:
vector.h(11) : see declaration of 'Vector'
stack.h(13) : see reference to class template instantiation 'Stack<T>' being compiled
Here is the Vector.h file:
#include<iostream>
using namespace std;
const int SIZEFACTOR = 4;
template <class T>
class Vector{
private:
unsigned int size_Of_Vector; // # of Items in list
unsigned int total_Vector_Capacity;//Total Capacity
T * vector_array;//Items themselves
public:
Vector();
~Vector();
void push_back(const T &e);
void pop_back();
bool empty();
int size() const;
void growVector();
void shrinkVector();
void shrinkToSize();
int currentCapacity() const;
//Operator
const T & operator [] (int index){
if((index >= size_Of_Vector) || index < 0){
cout << "ERROR! Index not used: " << index
<< " (max = " << size_Of_Vector << ")" << endl;
return EXIT_FAILURE;
}
return vector_array[index];
};//End Operator
};//End Header Definition
template <class T>
Vector<T>::Vector(){//Constructor
total_Vector_Capacity = 2;//Initially two items
size_Of_Vector = 0;//Nothing is in the vector yet
vector_array = new T [total_Vector_Capacity];//Initially two items
}
template <class T>
Vector<T>::~Vector (){//Destructor
total_Vector_Capacity = 0;
size_Of_Vector = 0;
delete [] vector_array;
}
template <class T>
void Vector<T>::growVector(){
total_Vector_Capacity = total_Vector_Capacity * SIZEFACTOR; //Quarter Size
//Temp Array
T * temp_array;
temp_array = new T [total_Vector_Capacity];
//Copy
for(unsigned int i = 0; i < size_Of_Vector; i++){
temp_array[i] = vector_array[i];
}
//Delete old array
delete [] vector_array;
//Re-initilize main array
vector_array = new T [total_Vector_Capacity];
//Copy old Data back to original array
for(unsigned int i = 0; i < size_Of_Vector; i++){
vector_array[i] = temp_array[i];
}
//Delete temp array
delete [] temp_array;
}
template <class T>
void Vector<T>::shrinkVector(){
total_Vector_Capacity = (int) (total_Vector_Capacity / SIZEFACTOR); //Quarter Size
//Temp Array
T * temp_array;
temp_array = new T [total_Vector_Capacity];
//Copy
for(unsigned int i = 0; i < size_Of_Vector; i++){
temp_array[i] = vector_array[i];
}
//Delete old array
delete [] vector_array;
//Re-initilize main array
vector_array = new T [total_Vector_Capacity];
//Copy old Data back to original array
for(unsigned int i = 0; i < size_Of_Vector; i++){
vector_array[i] = temp_array[i];
}
//Delete temp array
delete [] temp_array;
}
template <class T>
void Vector<T>::shrinkToSize(){
total_Vector_Capacity = size_Of_Vector; //Quarter Size
//Temp Array
T * temp_array;
temp_array = new T [total_Vector_Capacity];
//Copy
for(unsigned int i = 0; i < size_Of_Vector; i++){
temp_array[i] = vector_array[i];
}
//Delete old array
delete [] vector_array;
//Re-initilize main array
vector_array = new T [total_Vector_Capacity];
//Copy old Data back to original array
for(unsigned int i = 0; i < size_Of_Vector; i++){
vector_array[i] = temp_array[i];
}
//Delete temp array
delete [] temp_array;
}
template <class T>
void Vector<T>::push_back(const T &e){
if(size_Of_Vector == total_Vector_Capacity){//Resize if size equals capacity
cout << "\nGrow now\n";
growVector();
}
vector_array[size_Of_Vector]=e;
size_Of_Vector++;//Increase Vector Size
}
template <class T>
void Vector<T>::pop_back(){
if(size_Of_Vector == (int)(total_Vector_Capacity/SIZEFACTOR)){//Resize if size equals capacity
cout << "\nShrink now\n";
shrinkVector();
}
size_Of_Vector--;//Increase Vector Size
}
template <class T>
bool Vector<T>::empty(){
if(size_Of_Vector==0){
return true;
}
else{
return false;
}
}
template <class T>
int Vector<T>::size() const{
return size_Of_Vector;
}
template <class T>
int Vector<T>::currentCapacity() const{
return total_Vector_Capacity;
}
and stack.h:
template <class T>
class Stack : public Vector{
private:
Vector<T> stack;
public:
Stack(){};
void push(T x) {stack.push_back(&x)};
void pop(){stack.pop_back()};
bool empty(){stack.empty()};
};
You have defined Vector<T> as a member of Stack already, it's not necessary to inherit from Vector
Update
template <class T>
class Stack : public Vector{
//...
};
To:
template <class T>
class Stack {
Vector<T> stack;
//...
};
Or if you want to inherit from a template class, you need to provide template parameter
template <class T>
class Stack : public Vector<T>{
// ^^^
Note:
You miss a few semicolons in Stack function definition and a bug in Stack::push_back as well, I may suggest update to below:
template <class T>
class Stack
{
private:
Vector<T> stack;
public:
Stack(){};
void push(T const& x) {stack.push_back(x);}
void pop(){stack.pop_back();}
bool empty(){return stack.empty();}
};

segmentation fault C++

I don't know why my code is seg faulting, im assuming im looking at a point in the queue where theres nothing there, but I thought that I do push elements onto the queue.
heres my code:
template <typename T>
class btree {
public:
btree(size_t maxNodeElems);
~btree() {}
struct node {
list <T> elements;
node *lvl;
};
private:
size_t maxNodeElems;
node* root;
};
template <typename T>
btree<T>::btree(size_t maxNodeElems) {
if (maxNodeElems > 0) max = maxNodeElems;
root = new node;
root->lvl = new node*[max+1];
for (int i = 0; i < (int) max+1; i++) root->lvl[i] = new node;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const btree<T>& tree) {
queue <typename btree<T>::node*> q;
q.push(tree.root);
int loop = 0;
while (!q.empty()) {
loop++;
typename btree<T>::node* temp = q.front();
int i = 0;
class list <T>::iterator itr = temp->elements.begin();
for (; itr != temp->elements.end(); ++itr) {
os << *itr << " ";
if (!temp->lvl[i]->elements.empty()) {
q.push(temp->lvl[i]);
}
i++;
}
q.pop();
}
return os;
}
could someone help me out, im lost because when I check if the if statement is working inside the for loop, it does go into it, but im not sure if its pushing
EDIT: more code
template <typename T>
pair <typename btree<T>::iterator, bool> btree <T>::insert (const T& elem) {
pair <typename btree<T>::node, bool> start;
start = addElement (elem, root);
pair <typename btree<T>::iterator, bool> final;
return final;
}
template <typename T>
pair <typename btree<T>::node, bool> btree<T>::addElement (const T& e, typename btree<T>::node*& n) {
pair <typename btree<T>::node, bool> elemPair;
if (n->elements.size() == max) {
int count = 0;
class list <T>::iterator itr = n->elements.begin();
for (; itr != n->elements.end(); ++itr) {
count++;
if (e < *itr) {
count--;
elemPair = addElement (e, n->lvl[count]);
} else if (e == *itr) return make_pair (*n, false);
}
} else {
n->elements.push_back(e);
n->elements.sort();
}
return make_pair(*n, true);
}
in my test.cpp:
int main (void) {
btree<char> b(2);
b.insert('Z'); b.insert('J'); b.insert('Y');
cout << b;
return 0;
}
The code you post doesn't compile and so I can't verify your error.
The following does compile and so might provide some help. Its similar to the code you provided.
However, the following is not good code - for example, you need to be vary careful about using the new keyword in a constructor, because exception handing in a constructor is more difficult (and there is the chance of an allocation exception being thrown).
template <typename T>
class btree {
public:
btree(size_t maxNodeElems);
//if your using new then you need to delete - do that in the destructor.
~btree();
struct node {
list <T> elements;
//you use this as a pointer to an array,
// it can be demoted to a double pointer -
// but not a single pointer as you had.
node ** lvl;
};
private:
size_t maxNodeElems; //you don't actually use this variable in your code
node* root;
//You are doing memory allocations in the constructor,
// therefore need to overload operator= and copy constructor.
// Since we are not overloading these, we make them private.
void operator=(const btree&);
btree(const btree&);
};
//In your code you had a undeclared variable max.
// No idea what it was or why you had it - removed.
template <typename T>
btree<T>::btree(size_t v_maxNodeElems)
: maxNodeElems(v_maxNodeElems) // construct the variable you define
{
root = new node;
root->lvl = new node*[maxNodeElems+1]; //root->lvl is a double pointer
for (int i = 0; i < (int) maxNodeElems+1; i++)
root->lvl[i] = new node;
}
//delete in reverse order to you constructing
template <typename T>
btree<T>::~btree() {
for (int i = 0; i < (int) maxNodeElems+1; i++)
delete root->lvl[i]; //first the elements of the array
delete[] root->lvl; //then the array - note the delete[]
delete root; //then the root.
}
int
main (int ac, char **av)
{
btree<char> b(2);
}