so the code, basically an AList with multiple functions, I have below currently runs fine and my passes all assertions and test cases that are assigned to my assignment, however, I lose .5 points because of a memory error. I believe the error lies somewhere in my copy constructor, but I am currently struggling to know where is the issue.
This is how my code looks along with my copy constructor.
#ifndef __ALIST_H__
#define __ALIST_H__
// size should not be negative
typedef unsigned long size_t;
#define RFACTOR 2 // use factor 2
namespace ds {
template <typename ItemType> class TestDriver; // for autograding; please ignore
/** Array-based list. */
template <typename ItemType> class AList {
friend class TestDriver<ItemType>; // for autograding; please ignore
private:
/** The underlying array. */
ItemType *items;
/** Stores the current size of the list. */
size_t count;
/** Max number of items allowed. */
size_t maxCnt;
/** Resize the underlying array to the target capacity. */
void resize(size_t capacity) {
maxCnt = capacity;
ItemType *a = new ItemType[maxCnt];
for (size_t i = 0; i < count; i++) {
a[i] = items[i];
}
delete[] items;
items = a;
}
public:
/**
* Construct a new AList object.
*
* #param initSize initial size of the underlying array; default 100
*/
AList(size_t initSize = 100) {
count = 0;
maxCnt = initSize;
items = new ItemType[maxCnt];
}
/** Destroy the AList object. */
~AList() { delete[] items; }
/** Return the number of elements in list. */
size_t size() const { return count; }
/** Return the i-th item in list .*/
ItemType &get(int i) const { return items[i]; }
/** Append `x` to the end of list. */
void addLast(ItemType x) {
if (count == maxCnt) {
resize(count * RFACTOR);
}
items[count] = x;
count += 1;
}
/** Return the last item in list. */
ItemType &getLast() const { return items[count - 1]; }
/** Delete and return the last item. */
ItemType removeLast() {
ItemType returnItem = getLast();
count -= 1;
return returnItem;
}
AList(const AList<ItemType> &other);
void addFirst(ItemType x);
ItemType &getFirst() const;
ItemType removeFirst();
};
/** Copy constructor. */
template <typename ItemType>
AList<ItemType>::AList(const AList<ItemType> &other) {
// TODO: create a list that is identical to `other`
count = other.count;
maxCnt = other.maxCnt;
ItemType arr[maxCnt];
items = new ItemType[maxCnt];
for(size_t i = 0; i < count; i++)
{
items[i] = arr[i];
}
delete [] items;
items = other.items;
}
/** Insert x at the front of list. */
template <typename ItemType> void AList<ItemType>::addFirst(ItemType x) {
// TODO:
if(count == maxCnt)
{
resize(count * RFACTOR);
}
for(size_t i = count; i > 0; i--)
{
items[i] = items[i - 1];
}
items[0] = x;
count = count + 1;
}
/** Return the first element in list. */
template <typename ItemType> ItemType &AList<ItemType>::getFirst() const {
// TODO:
return items[0];
}
/** Delete and return the first element in list. */
template <typename ItemType> ItemType AList<ItemType>::removeFirst() {
// TODO:
ItemType temp = items[0];
for(size_t i = 0; i < count - 1; i++)
{
items[i] = items[i + 1];
}
count = count - 1;
return temp;
}
} // namespace ds
#endif // __ALIST_H__
When I run my code, this is what the memory error states:
Output: 'original list: [1]; copy & getFirst: 1; resulting list: [1]'
217Expected: 'original list: [1]; copy & getFirst: 1; resulting list: [1]'
218Error(s):
219==190== Invalid free() / delete / delete[] / realloc()
220==190== at 0x483D74F: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
221==190== by 0x10979A: ds::AList<int>::~AList() (AList.h:51)
222==190== by 0x10962E: main (test_driver.cpp:55)
223==190== Address 0x4da3cc0 is 0 bytes inside a block of size 4 free'd
224==190== at 0x483D74F: operator delete[](void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
225==190== by 0x10979A: ds::AList<int>::~AList() (AList.h:51)
226==190== by 0x109608: main (test_driver.cpp:96)
227==190== Block was alloc'd at
228==190== at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
229==190== by 0x109761: ds::AList<int>::AList(unsigned long) (AList.h:47)
230==190== by 0x10939F: main (test_driver.cpp:55)
231==190==
main program:
#define CATCH_CONFIG_MAIN
#include "AList.h"
#include "catch.hpp"
#include <cstdlib>
#define SIZE 5
TEST_CASE("All") {
ds::AList<int> L;
// randomly add SIZE ints to the array
int nums[SIZE];
srand(time(0)); // setting the seed for rand()
for (int i = 0; i < SIZE; i++) {
nums[i] = rand() % 20 + 1; // generating random numbers by rand()
L.addLast(nums[i]);
}
SECTION("copy constructor") {
ds::AList<int> *K = new ds::AList<int>(L);
CHECK(L.size() == K->size());
CHECK(K->getLast() == nums[SIZE - 1]);
delete K; // this should not also delete L
}
SECTION("addFirst") {
L.addFirst(123);
L.addFirst(234);
CHECK(L.getFirst() == 234);
CHECK(L.get(2) == nums[0]);
}
SECTION("removeFirst") {
int x = L.removeFirst();
CHECK(x == nums[0]);
CHECK(L.getLast() == nums[SIZE - 1]);
}
}
If anyone could give any tips or suggestions on how I can fix this, it would be greatly appreciated!
Related
i have this reSize function in my Array header
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
and my main code:
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
the problem is after resizing, my values that were stored in "data" variable are gone.
when i commented the code.
//delete[] old
in the reSize function
it worked fine...so i guess the problem is when i delete the pointer it deletes also the pointer inside the struct object which i don't want it to happen..
i don't want to comment the command becuz a leak in the memory will happen...how to fix this problem ?.
Update: My Array Class .
#include <iostream>
using namespace std;
template <class T>
class Array {
private :
T* items;
int size;
int length;
public :
Array() {
this->size = 0;
items = new T[this->size];
length = 0;
}
Array(int size) {
this->size = size;
items = new T[this->size];
length = 0;
}
int getsize() {
return this->size;
}
template <class T> void push_back(T x) {
if ((length+1) <= size) {
items[length] = x;
length++;
}
else {
this->reSize(size+1);
items[length] = x;
length++;
}
}
template <class T> void Insert(int index, T x) {
if (length + 1 <= size) {
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[index] = x;
length++;
}
else {
this->reSize(size+1);
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[length] = x;
length++;
}
}
template <class T> int Find(T x) {
int index = -1;
for (int i = 0;i < length;i++) {
if (items[i] ==x) {
index = i;
break;
}
}
return index;
}
void remove(int index) {
items[index] = "";
if(index+1 < length)
for (int i = index;i < length-1;i++) {
items[i] = items[i + 1];
items[i + 1] = "";
}
length--;
}
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
void Merge(Array<T> x){
T* old = items; int oldlength = length;
items = new T[size + x.size];
size = size + x.size;
length += x.length;
for (int i = 0;i < length;i++) {
if(i< oldlength)
items[i] = old[i];
else
items[i] = x.items[i-oldlength];
}
delete[] old;
}
T& get(int index) {
return items[index];
}
}
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
// this line causes some problems
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
In your code, declaring Array<User> x(3) declares an empty array with 3 elements that are preallocated. The length property of the array is 0. When the array is copied, length(0) elements are copied over into the resized storage. When you access the 0th element, it won't be copied on resize. What you actually need to do is call push_back() to add an element to the array so that length becomes 1 and the element is copied on resize.
Also, your array class is lacking a proper copy constructor and move constructor, which means copying it won't work at all. This means that User cannot be copied properly since it contains an array, which means that resizing an array of User won't work. You need to implement a copy constructor and copy assignment operator to be able to copy the array. You also need a destructor since, right now, the array is leaking memory when it goes out of scope.
I have some doubts about my insert method. it is compiling, but with no result. I presume that it is containing some coding errors. Can you help me resolving this? Thanks in advance.
private:
T* elements;
int capacity;
int nbElements;
template <class T>
void TableDynamic<T>::insert(const T& element, int index)
{
int *temp = new int[capacity] ;
for(int i =0; i<nbElements; i++)
{
temp[i] = element;
}
delete[] elements;
int *elem = new int[capacite];
}
I have written some code for you. see if its works for you.
#include <iostream>
using namespace std;
// insert element using template
template <class T>
class TableDynamic
{
private:
T *elements;
int capacity;
int nbElements;
public:
TableDynamic(int capacity)
{
this->capacity = capacity;
this->nbElements = 0;
this->elements = new T[capacity];
}
void insert(const T &element, int index)
{
if (index < 0 || index > nbElements)
{
cout << "Index out of range" << endl;
return;
}
if (nbElements == capacity)
{
cout << "Table is full" << endl;
return;
}
for (int i = nbElements; i > index; i--)
{
elements[i] = elements[i - 1];
}
elements[index] = element;
nbElements++;
}
void print()
{
for (int i = 0; i < nbElements; i++)
{
cout << elements[i] << " ";
}
cout << endl;
}
};
int main()
{
TableDynamic<int> table(10);
table.insert(10, 0);
table.insert(20, 1);
table.insert(30, 2);
// print the table
table.print();
return 0;
}
temp and elem variables types should be T* , and in the last line you have wrote capacite, should be capacity
Resizing should only be done, if the capacity is insufficient.
Furthermore you didn't copy any of the old elements over; you simply fill every element with the new element.
Also you're generating an array of ints regardless of element type which will only allow for element types int or const int.
The code should look something like this:
template <class T>
void TableDynamic<T>::insert(const T& element, int index)
{
if ((index > nbElements) || (index < 0))
{
throw std::runtime_error("invalid index");
}
if ((nbElements + 1) > capacity)
{
// reallocate array
auto newCapacity = CalculateNewCapacity(capacity, nbElements + 1); // todo: implement capacity calulation function
auto temp = std::make_unique<T[]>(newCapacity);
temp[index] = element; // note copying may result in an error, moving shouldn't, so copy first
// move first half
std::move(elements, elements + index, temp.get());
// move second half
std::move(elements + index, elements + nbElements, temp.get() + (index + 1));
// replace array
delete[] elements;
elements = temp.release();
capacity = newCapacity;
}
else
{
// make room for new element
std::move_backward(elements + index, elements + nbElements, elements + (nbElements + 1));
// insert new element
elements[index] = element;
}
++nbElements;
}
I am attempting to implement my own version of a C++ vector, but I'm having issues with my reallocation function when the size becomes equal to the capacity. Specifically, when the debugger reaches the delete line, I am given a heap corruption error stating that the application wrote to memory after the end of the heap buffer. Could someone give advice on why my approach is wrong? Please let me know if there is any other information needed that would be helpful in solving this issue.
EDIT: I have added all of my current code so that others can test the program and reproduce the issue.
Header file:
#ifndef VECTOR_H
#define VECTOR_H
template <class ItemType> class Vector{
public:
Vector();
Vector(int capacity);
int size();
int capacity();
bool is_empty();
ItemType at(int index);
void push(ItemType newItem);
void printItems();
~Vector();
private:
int m_capacity; // number of items we can hold
int m_size; // current number of items
int m_unitSize; // size of one unit (used for arithmetic in indexing)
ItemType* m_vectorPtr; // pointer to actual vector
void reallocate(); // reallocates memory if array is filled
};
#endif
Implementations and testing:
#include <iostream>
#include "Vector.h"
#include <assert.h>
// default constructor
template <class ItemType>
Vector<ItemType>::Vector()
:m_capacity(0), m_size(0) {
m_unitSize = sizeof(ItemType);
m_vectorPtr = nullptr;
}
// constructor with given number of items
template <class ItemType>
Vector<ItemType>::Vector(int capacity)
:m_size(0){
int x = 1;
while (x <= capacity) {
x *= 2;
}
m_unitSize = sizeof(ItemType);
m_capacity = x;
m_vectorPtr = new ItemType[capacity];
}
// return total possible items
template <class ItemType>
int Vector<ItemType>::capacity() {
return m_capacity;
}
// return current number of elements
template <class ItemType>
int Vector<ItemType>::size() {
return m_size;
}
// return whether the vector is currently empty
template <class ItemType>
bool Vector<ItemType>::is_empty() {
return m_size == 0;
}
// return the item at a given index
template<class ItemType>
ItemType Vector<ItemType>::at(int index) {
return m_vectorPtr[index];
}
// reallocate the array if it becomes full
template <class ItemType>
void Vector<ItemType>::reallocate() {
if (m_size >= m_capacity) {
// allocate a new array twice the capacity
m_capacity *= 2;
ItemType* newVector = new ItemType[m_capacity];
for (int i = 0; i < m_size; i++) {
newVector[i] = m_vectorPtr[i];
}
delete[] m_vectorPtr;
m_vectorPtr = newVector;
}
}
// push an item onto the vector at the end
template<class ItemType>
void Vector<ItemType>::push(ItemType newItem) {
if (m_size >= m_capacity) {
// reallocate memory for the vector
reallocate();
}
// push new item onto vector
m_vectorPtr[m_size] = newItem;
m_size++;
}
template <class ItemType>
void Vector<ItemType>::printItems() {
for (int i = 0; i < m_size; i++) {
std::cout << m_vectorPtr[i] << " ";
}
std::cout << std::endl;
}
template <class ItemType>
Vector<ItemType>::~Vector() {
delete[] m_vectorPtr;
}
// test here
int main() {
// initialize a vector
int startingCapacity = 3;
Vector<int> testVector(startingCapacity);
assert(testVector.capacity() == 4 &&
testVector.size() == 0 &&
testVector.is_empty() == true);
// add two items to the vector
testVector.push(3);
testVector.push(7);
assert(testVector.capacity() == 4 &&
testVector.size() == 2 &&
testVector.is_empty() == false);
// print the two items
testVector.printItems();
// add past capacity to test reallocate
testVector.push(5);
testVector.push(8);
testVector.push(6);
assert(testVector.capacity() == 8 &&
testVector.size() == 5 &&
testVector.is_empty() == false);
testVector.printItems();
std::cout << "All test cases passed." << std::endl;
return 0;
}
You have to reallocate before you change m_size because the for loop will be incorrect if m_size > m_capacity and you'll access m_vectorPtr past its size. And make sure the new capacity is big enough (m_capacity *= 2) > new_size
template <class ItemType>
void Vector<ItemType>::reallocate(size_t new_size) {
if (new_size > m_capacity) {
// allocate a new array twice the capacity
if (m_capacity == 0)
m_capacity = 10;
while (m_capacity < new_size)
m_capacity *= 2;
ItemType* newVector = new ItemType[m_capacity];
for (int i = 0; i < m_size; i++) {
newVector[i] = m_vectorPtr[i];
}
delete[] m_vectorPtr;
m_vectorPtr = newVector;
}
}
And here sample push_back method reallocating before changing m_size:
void push_back(ItemType item) {
reallocate(m_size + 1);
m_vectorPtr[m_size] = item;
m_size++;
}
Demo
UPDATE
You have a small bug in the constructor NOT:
m_vectorPtr = new ItemType[capacity];
but
m_vectorPtr = new ItemType[m_capacity];
because capacity is the requested one, not the power of two you want (3, not 4 in your test).
I am working on a project which I have to include a header file to my main.cpp. The header file is a heap which is using a template file. For reasons that escape me the insert and remove functions cannot be "seen" in the main file. I am getting an error message: C:/Users/Tito/Documents/C++proj/cs3304/Homework2_2/Homework10/main.cpp:58:17: error: request for member 'remove' in 'enter1', which is of non-class type 'priority_queue_heap()'. Can someone please tell me where I am going wrong? I will really appreciate it.
Thanks
Here are the lines of code:
Main.cpp:
/**
* Insert a few elements into a heap and the remove them
* one by one and see if we get them in the right.
*/
#include "priority_queue_heap.h"
#include "heap.h"
#include <iostream>
#include <ctime>
using namespace std;
int test1() {
heap<int> hp;
hp.insert(1);
hp.insert(2);
hp.insert(3);
hp.insert(4);
hp.insert(5);
hp.check_heap();
int x = hp.remove();
cout << "removed " << x << endl;
x = hp.remove();
cout << "removed " << x << endl;
x = hp.remove();
cout << "removed " << x << endl;
x = hp.remove();
cout << "removed " << x << endl;
x = hp.remove();
cout << "removed " << x << endl;
cout << "empty? " << hp.is_empty() << endl;
}
void test2() {
srand(time(NULL));
heap<int> hp;
for(int i = 0; i < 30; i++ ) {
hp.insert(rand());
}
while(!hp.is_empty()) {
int x = hp.remove();
cout << x << endl;
}
}
int main() {
/*test1();
test2();*/
priority_queue_heap<int> enter1();
enter1.insert(135);
enter1.insert(909);
enter1.insert(203);
cout<<endl;
cout<< "values to be removed" << endl;
cout << enter1.remove() << endl;
}
heap.h:
#ifndef HEAP_H
#define HEAP_H
/**
* This class implements a heap as described in the text.
* We will treat it as a priority queue.
*/
template <class T>
class heap {
public:
static const int CAPACITY = 10;
heap() {
size = 0;
}
bool is_empty() const { return size == 0;}
bool is_full() const { return size == CAPACITY; }
/**
* Remove the largest value from this heap and return it.
*
* Precondition: heap is not empty.
*/
T remove();
/**
* Inserts the 'value' into the heap.
*
* Precondition: heap is not full
*/
void insert(const T& value);
/**
* Check if the heap is valid.
* Prints out each parent and its children (for all nodes with children)
* Stops when a parent is less than one or both of its children
* Prints 'check' for each parent that is greater than or equal to its
children
*/
bool check_heap();
private:
T data[CAPACITY];
int size;
};
#include "heap.template"
#endif // HEAP_H
heap.template:
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <iomanip>
/*
* parent index is p, children are at indices 2*p+1 and 2*p+2
* You must check that those are in range
*
* child index is c, parent index is (c-1)/2 (integer division)
*/
/**
* Inserts the 'value' into the heap.
*
* Precondition: heap is not full
*/
template <class T>
void heap<T>::insert(const T& value) {
assert(!is_full());
//std::cout << size << std::endl;
// add the value to a new node in proper position
data[size] = value;
size++;
// move the value up the tree as needed
int child = size-1; // index of the new 'node'
int parent = (child-1)/2; // index of the parent
while((child > 0) && (data[parent] < data[child])) {
// swap parent and child values
T tmp = data[parent];
data[parent] = data[child];
data[child] = tmp;
// update parent and child
child = parent; // this is where new value is!
parent = (child-1)/2;
}
// it's a heap!
}
/**
* Remove the largest value from this heap and return it.
*
* Precondition: heap is not empty.
*/
template <class T>
T heap<T>::remove() {
assert(!is_empty());
// grab first element, save it for return later
T save = data[0];
// copy last value in list to the beginning
// decrement size
data[0] = data[size-1];
size--;
// size--;
// data[0] = data[size];
// sift the new first element down until it finds its place
int parent = 0;
int left_child = 2*parent+1;
int right_child = 2*parent+2;
bool still_working = true;
while(still_working && left_child < size) { // while the parent has at
least one child
if(right_child >= size) {
// only the left child to worry about
if(data[parent] < data[left_child]) {
// out of order, so swap them
T t = data[parent];
data[parent] = data[left_child];
data[left_child] = t;
parent = left_child;
still_working = false; // we must be done!
} else {
still_working = false;
}
} else {
// two children
if(data[left_child] > data[right_child]) {
//left child larger
if(data[parent] < data[left_child]) {
// out of order, so swap them
T t = data[parent];
data[parent] = data[left_child];
data[left_child] = t;
parent = left_child;
} else {
still_working = false;
}
} else {
// right child larger
if(data[parent] < data[right_child]) {
// out of order, so swap them
T t = data[parent];
data[parent] = data[right_child];
data[right_child] = t;
parent = right_child;
} else {
still_working = false;
}
}
left_child = 2*parent + 1;
right_child = 2*parent + 2;
}
}
return save;
}
/**
* Check if the heap is valid.
* Prints out each parent and its children (for all nodes with children)
* Stops when a parent is less than one or both of its children
* Prints 'check' for each parent that is greater than or equal to its
children
*/
template <class T>
bool heap<T>::check_heap() {
for(int p = 0; p < size; p++ ) {
int cl = 2*p+1;
int cr = 2*p+2;
std::cout << std::setw(5) << p << std::setw(10) << data[p];
if(cl < size) { // p has a left child?
std::cout << std::setw(10) << data[cl];
if(data[p] < data[cl]) {
std:exit(1);
}
}
if(cr < size) { // p has a right child?
std::cout << std::setw(10) << data[cr];
if(data[p] < data[cr])
std::exit(1);
}
std::cout << std::endl;
}
return true;
}
priority_queue_simple.template:
#include <cassert>
/**
* Remove the largest value from this priority queue and return it.
*
* Precondition: priority queue is not empty.
*/
template <class T>
T priority_queue_simple<T>::remove() {
assert(size > 0);
int imax = 0;
for(int i = 1; i < size; i++ ) {
if(data[i] > data[imax])
imax = i;
}
T tmp = data[imax];
data[imax] = data[size-1];
size--;
return tmp;
}
/**
* Inserts the 'value' into the priority queue.
*
* Precondition: priority queue is not full
*/
template <class T>
void priority_queue_simple<T>::insert(const T& value) {
assert(size < CAPACITY);
size++;
data[size-1] = value;
}
priority_queue_heap.h:
#ifndef PRIORITY_QUEUE_HEAP_H
#define PRIORITY_QUEUE_HEAP_H
//#include "heap.h"
template <class T>
class priority_queue_heap {
priority_queue_heap();
bool is_empty() const;
bool is_full() const;
/**
* Remove the largest value from this priority queue and return it.
*
* Precondition: priority queue is not empty.
*/
T remove();
/**
* Inserts the 'value' into the priority queue.
*
* Precondition: priority queue is not full
*/
void insert(const T& value);
private:
heap<T> pri_que;
};
#include "priority_queue_heap.template"
#endif // PRIORITY_QUEUE_HEAP_H
template <class T>
T priority_queue_heap<T>::remove()
{
return pri_que.remove();
}
priority_queue_heap.template:
template <class T>
T priority_queue_heap<T>::remove()
{
return pri_que.remove();
}
template <class T>
void priority_queue_heap<T>::insert(const T& value)
{
pri_que.insert(value);
}
priority_queue_simple.h:
#ifndef PRIORITY_QUEUE_SIMPLE_H
#define PRIORITY_QUEUE_SIMPLE_H
/**
* This class implements a priority queue using a very simple strategy:
* Store the values in an array.
* Add new values at the end.
* When asked to remove a value, search for the largest (linear search)
*
*/
template <class T>
class priority_queue_simple {
public:
static const int CAPACITY = 30;
priority_queue_simple() {
size = 0;
}
bool is_empty() const {
return size == 0;
}
bool is_full() const {
return size == CAPACITY;
}
/**
* Remove the largest value from this priority queue and return it.
*
* Precondition: priority queue is not empty.
*/
T remove();
/**
* Inserts the 'value' into the priority queue.
*
* Precondition: priority queue is not full
*/
void insert(const T& value);
private:
T data[CAPACITY];
int size;
};
#include "priority_queue_simple.template"
#endif // PRIORITY_QUEUE_SIMPLE_H
You should remove the "()" characters after enter1 at line 51 of main.cpp ...
Otherwise c++ sees that as a function, it does not call the constructor.
You have a subtle error in your heap declaration (main.cpp:57):
priority_queue_heap<int> enter1();
Here you are actually declaring a prototype for the enter1 function that takes no argument and returns a priority_queue_heap<int>. Just remove the parentheses to actually declare a variable:
priority_queue_heap<int> enter1;
priority_queue_heap<int> enter1();
Is interpreted by the compiler as a function named enter1 that returns a priority_queue_heap<int> and takes no parameters. When you use
cout << enter1.remove() << endl;
You are trying to call a member function on a name that the compiler interpreted as a function so that is why it tells you it is of non class type. Remove the () from enter1 so you have
priority_queue_heap<int> enter1;
and now enter1 will be an object of type priority_queue_heap<int>
I am receiving the error "expression must have pointer-to-class type". I have searched the error and have not been able to find a post that I could figure out what is going on. I am receiving the error on Sequence2.cpp on line 49 (data->resize( capacity * 2 );)
Sequence2.h
typedef double value_type;
class sequence
{
private:
value_type* data;
int used;
int current_index;
int capacity;
public:
// TYPEDEFS and MEMBER CONSTANTS
static const int DEFAULT_CAPACITY = 5;
// CONSTRUCTORS and DESTRUCTOR
sequence(int initial_capacity = DEFAULT_CAPACITY);
sequence(const sequence& source);
~sequence();
// MODIFICATION MEMBER FUNCTIONS
void insert(const value_type& entry);
void resize(int new_capacity);
// ADDITIONAL FUNCTIONS THAT ARE NOT RELEVANT
Sequence2.cpp
#include "stdafx.h"
#include "Sequence2.h"
// Postcondition: The sequence has been initialized as an empty sequence.
// The insert/attach functions will work efficiently (without allocating
// new memory) until this capacity is reached.
sequence::sequence(int initial_capacity)
{
capacity = initial_capacity;
current_index = -1;
data = new value_type[DEFAULT_CAPACITY];
}
sequence::sequence(const sequence & source)
{
// NEED TO DO
// Postcondition: the sequence has made a deep copy of the source sequence.
}
sequence::~sequence()
{
delete[] data;
}
// Postcondition: A new copy of entry has been inserted in the sequence
// before the current item. If there was no current item, then the new entry
// has been inserted at the front of the sequence. In either case, the newly
// inserted item is now the current item of the sequence.
void sequence::insert(const value_type & entry)
{
if (current_index < 0)
{
current_index = 0; // Set current index to first index
data[current_index] = entry;
used++;
}
else
{
if (used < capacity) {
data[current_index + 1] = entry;
current_index++;
used++;
}
else
{
data->resize( capacity * 2 );
}
}
}
void sequence::resize(int new_capacity)
{
value_type *temp = new value_type[capacity];
int temp_capacity = capacity;
for (int i = 0; i < capacity; i++)
{
temp[i] = data[i];
}
delete[] data;
data = new value_type[new_capacity];
for (int i = 0; i < temp_capacity; i++)
{
data[i] = temp[i];
used++;
current_index++;
}
delete[] temp;
}
resize is a member function too, you're not calling it correctly. Change
data->resize( capacity * 2 );
to
resize( capacity * 2 );
Here're some other issues:
You might need to insert the value after calling resize() in insert().
No need to new/delete twice in resize().
The value of used and current_index seems wrong after resize().