How to store multiple queue in array? - c++

I have a queue class where I implement the queue structure.
#include "queue.h"
Queue::Queue()
{
}
Queue::Queue(int size){
front = rear = -1;
this->size = size;
Q = new int[size];
}
void Queue::enqueue(int x){
if (rear == size -1 ){
cout << " its full" << endl;
}else{
rear ++;
Q[rear] = x;
}
}
int Queue::dequeue(){
int x= -1;
if (rear == front){
cout << " its empty"<<endl;
}else{
front ++;
x = Q[front];
}
return x;
}
void Queue::Display(){
for(int i= front+1; i<=rear; i++){
cout << Q[i] << " ";
}
cout << endl;
}
bool Queue::isEmpty(){
return (size==0);
}
int Queue::peek()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
return Q[front];
}
In main.cpp, I create multiple queues. I am trying to implement a scheduling algorithm where I need to process each queue in order. The problem starts when I try to go through each queue. I would like to use only one for loop to access the element of each queue rather than for loop for each of them.
Example:
queue[1..N] where N is the number of queues. In for loop, I want to check if queue[i].empty().

I found a solution to the problem. In the main.cpp, following code solved the issue.
Queue allQueues[4];
allQueues[0] = queue1;
allQueues[1] = queue2;
allQueues[2] = queue3;
allQueues[3] = queue4;
To access:
for(int i=0; i<4; i++){
if allQueues[i].empty(){
//do something
}
}

If you need to generate a specific number of instances of your Queue class that is fixed and known at compile time, your code solution will work. However, if you have a program where new Queue instances need to be created while the program is running, you need to use dynamic memory allocation on the heap.
One approach to this is to create an array or a vector of pointers to your Queue class in main.cpp. The std::vector is more flexible, and it's best to use a smart pointer to create each instance of Queue, although many academic courses won't allow use of the standard template library or of smart pointers, and in that case you need just a normal array of pointers to Queue and use new and delete appropriately.
const int SIZE = 100 //max number of Queue instances
Queue* allQueues[SIZE]; //array of uninitialized pointers to Queue
for (int i = 0; i < SIZE; i++) { //ensure all pointers are set to null
allQueues[i] = nullptr;
}
//To make a new Queue instance and insert it into the array:
allQueues[0] = new Queue();
//And when done with that Queue instance, to avoid memory leaks and dangling pointers:
delete allQueues[0];
allQueues[0] = nullptr;
(This is all much better done with std::array, or std::vector, and smart pointers).
Note also the memory usage, without this approach you have two full-sized instances of Queue for queue1, instead of the object itself and a pointer to that object. However, one can do the array of pointers thing using only automatic stack allocation as well, but in that case, you don't want to be creating new objects at runtime. For that, it's simple:
Queue* allQueues[4];
allQueues[0] = &queue1;
//etc.
P.S. One problem with your solution is that when you do this assignment:
allQueues[0] = queue1;
You need a copy constructor in your class, or an overloaded '=' operator, to ensure that all of queue1's internals are correctly copied over into the the array of Queue objects, and avoid all the 'shallow copy' issues.
Queue::Queue(const Queue& copySource) {
this->size = copysource.size;
this->Q = new int[copysource.size];
for (int i = 0; i < size; i++) {
this->Q[i] = copysource.Q[i];
}
See:
Why can I access private variables in the copy constructor?

Related

Why does this function give me a segmentation fault?

I am currently trying to create a linked list which has two elements, usernames and seconds. It is supposed to read from a file and save it into two vectors.
I'm not sure why, but when I attempt to collect the data and store it into a linked list, I get a segmentation fault.
I'm kind of in a rutt, I feel like this should work.
Here is my code for main.cpp:
// main.cpp
int main() {
//Collect initial leaderboard data into two parallel vectors
cout << "here";
vector<string> playerNames;
vector<unsigned> playerTimes;
collect_data(playerNames, playerTimes);
cout << "here";
//Create a LeaderBoard object based on the data in the parallel vectors
LeaderBoard players(playerNames, playerTimes);
cout << "Initial leaderboard from https://www.speedrun.com/ac#All_Debts\n";
players.display();
cout << endl;
return 0;
}
//Leaderboard.cpp
LeaderBoard :: LeaderBoard(const vector<string>& usernames, const vector<unsigned>& second) //Combines both vectors to linked list;
{
for (int i = 0; i < usernames.size(); i++)
{
nPlayers_ ++;
Player *ptr = new Player;
ptr = nullptr;
ptr->username = usernames[i];
ptr->seconds = second[i];
if (head_ == nullptr)
{
head_ = ptr;
tail_ = ptr;
}
else
{
while (tail_-> next != nullptr)
{
tail_ = tail_ -> next;
}
tail_->next = ptr;
tail_ = ptr;
}
}
}
Can someone help me, or lead me towards the right direction?
In this part
Player *ptr = new Player;
ptr = nullptr;
ptr->username = usernames[i];
ptr->seconds = second[i];
You are overwriting the pointer to newly created object by nullptr, then dereferencing the nullptr. This will lead to memory leak and Segmentation Fault.
The line
ptr = nullptr;
should be removed from here.
Also it seems you forgot to initialize ptr->next.
ptr->next = nullptr;
should be added after that part.
This code presents some issues.
First of all, you might ditch heap allocation on each iteration of the for loop, using only once the allocation, before entering the loop. This prevents errors such as:
Player *ptr = new Player;
ptr = nullptr;
which causes segmentation fault in your code.
Another problem might be that head_ and tail_ might also be nullptr, so you have to check carefully about both.
You are allocating something on the heap, without caring about deleting the data later.
Why don't you use a std::vectorstd::unique_ptr<Player> to collect all the player scores, so at the end of the program, everything will be deleted?
//Assuming there's a vector like this in Leaderboard.h:
#include <memory>
std::vector<std::unique_ptr<Player>> players_{};
//Leaderboard.cpp
LeaderBoard::LeaderBoard(const vector<string>& usernames, const vector<unsigned>& second) //Combines both vectors to a final list;
{
for (int i = 0; i < usernames.size(); i++)
{
Player p{};
p.username = usernames[i];
p.seconds = second[i];
players_.emplace_back(std::move(Player));
}
}
In this way, you ditch tricky pointer handling problems, allocation problems, segmentation fault all together. As nice result, you have a vector that can be used with a broad range of algorithms

How to index array of pointers to arrays [queue]?

I am trying program a queue with arrays in C++.
I used this approach https://stackoverflow.com/a/936709/7104310 as shown below.
My question: How can I index the arrays to fill them?
In a normal 2d-array it would be arr[3][2] for example. But I do not know how to do this with pointers. The question hat not been answered in the Solution upon.
Thank you!
#include <iostream>
#define MAX_SIZE 3
using namespace std;
// ary[i][j] is then rewritten as
//arr[rear*capacity + front]
// Class for queue
class msg_queue
{
char **arr; // array to store queue elements
int capacity; // maximum capacity of the queue
int front; // front points to front element in the queue (if any)
int rear; // rear points to last element in the queue
int count; // current size of the queue
public:
msg_queue(int size = MAX_SIZE, int slot_length = MAX_SIZE); // constructor
void dequeue();
void enqueue(char x);
char peek();
int size();
bool isEmpty();
bool isFull();
};
// Constructor to initialize queue
msg_queue::msg_queue(int size, int slot_length)
{
arr = new char*[size];
for (int i = 0; i < size; ++i) {
arr[i] = new char[slot_length];
}
capacity = size;
front = 0;
rear = -1;
count = 0;
}
// Utility function to remove front element from the queue
void msg_queue::dequeue()
{
// check for queue underflow
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Removing " << arr[front] << '\n';
front = (front + 1) % capacity;
count--;
}
// Utility function to add an item to the queue
void msg_queue::enqueue(char item)
{
// check for queue overflow
if (isFull())
{
cout << "OverFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
cout << "Inserting " << item << '\n';
rear = (rear + 1) % capacity;
arr[rear] = item; //ERROR HERE
count++;
}
// Utility function to return front element in the queue
char msg_queue::peek()
{
if (isEmpty())
{
cout << "UnderFlow\nProgram Terminated\n";
exit(EXIT_FAILURE);
}
return arr[front]; //ERROR HERE
}
Well, it's still arr[3][2].
Although arrays are not pointers, the way we use them is effectively using a pointer because of the way they work and the way their name decays.
x[y] is *(x+y), by definition.
That being said, I would recommend you drop the 2D dynamic allocation (which is poison for your cache) and create one big block of Width×Height chars instead. You can use a little bit of maths to provide 2D indexes over that data.
Also you forgot to free any of that memory. If you use a nice std::vector to implement my suggested 1D data scheme (or even if you hire a vector of vectors, but ew!) then it'll be destroyed for you. Of course if you could do that then you'd probably be using std::queue…

C++ Where is the seg fault?

I am currently tackling this assignment for my computer science class:
Make your own dynamic array template. It should allow creating contiguous arrays (filled with things of the same type) which you can extend without worrying about running out of space.
Do one version using malloc and free.
Do one version using new and delete.
My version using new and delete works flawlessly; however, in trying to convert my new/delete code to using malloc/free, I keep getting a seg fault. I have narrowed down the segfault (I think), to being in a single function: addData. Take a look at the code in my main I used to test this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3->addData(7);
testArray4->printArray();
return 0;
This gives a seg fault; however, when I change it to this:
Array2<int> *testArray3 = new Array2<int>(5);
Array2<int> *testArray4;
testArray3->initArray();
testArray3->printArray();
testArray4 = testArray3; //->addData(7);
testArray4->printArray();
return 0;
There is no seg fault. This makes me believe the issue is in my addData function. Here is the code for that:
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
I am new to programming as a whole and have not completely wrapped my head around pointers and memory allocation, etc. Any advice you could give me would be greatly appreciated! In case you need to see the rest of the code, here is the entire file I coded my template in. Thank you so much for your time!
#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
using namespace std;
template<typename T>
class Array2{
public:
Array2(int size){
this->size = size;
data = (T *) malloc(sizeof(T)*size);
};
Array2<T> *addData(T dataToAdd){
Array2 <T> *tmp;
tmp->data = this->getData();
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
free(tmp->data);
free(this->data);
return newData;
};
~Array2(){
free(this->data);
};
void initArray(){
for (int i = 0; i < this->size; ++i){
//this->data[i] = i;
this->setData(i, i);
}
};
void printArray(){
//ostringstream oss;
string answer = "";
for (int i = 0; i < this->size; ++i){
//oss << this->data[i] + " ";
cout << this->data[i] << " ";
}
//answer = oss.str();
cout << answer << endl;
};
T* getData(){
return this->data;
}
int getSize(){
return this->size;
}
void setData(T data, int index){
this->getData()[index] = data;
}
private:
int size;
T* data;
};
Array2 <T> *tmp;
Allocates a pointer. This does not point the pointer at anything or allocate any storage for the pointer to point at. What it points at without being explicitly assigned is undefined. If you are lucky, and you are this time, tmp points at an invalid location and the program crashes. If you are unlucky, tmp points at some usable region of program memory and lets you write over it, destroying whatever information was there.
tmp->data = this->getData();
Attempts to access the data member at tmp, but fortunately for you the access is in invalid memory and the program comes to a halt. It also has tmp's data pointing at this's data, and that's a dangerous position to be in. Changes to one will happen to the other because they both use the same storage. Also think about what will happen to this->data if you free tmp->data.
Or perhaps I'm wrong and the halt is here for the same reason:
Array2 <T> *newData;
newData->data = (T *) malloc(sizeof(T)*(this->size + 1));
Both need to be fixed. tmp doesn't have to live long, so we can make it a temporary local variable.
Array2 <T> tmp;
Typically this will be created on the stack and destroyed when the function ends and tmp goes out of scope.
But this will not work because Array2's constructor requires a size so it can allocate the array's storage. You need to find out how big to make it. Probably something along the lines of:
Array2 <T> tmp(this->size + 1);
But frankly I don't think you need tmp at all. You should be able to copy the dataToAdd directly into newData without using tmp as an intermediary.
newData is eventually going to be returned to the caller, so it needs a longer scope. Time to use new.
Array2 <T> *newData = new Array2 <T>(this->size + 1);
And through the magic of the constructor... Wait a sec. Can't use new. That makes this hard. malloc doesn't call constructors, so while malloc will allocate resources for newData, it doesn't do the grunt work to set newData up properly. Rule of thumb is Never malloc An Object. There will be exceptions I'm sure, but you shouldn't be asked for this. I recommend using new here and politely telling the instructor they are on crack if they complain.
Anyway, new Array2 <T>(this->size + 1) will allocate the data storage for you with it's constructor.
There is an easier way to do this next bit
for (int i = 0; i < tmp->getSize() + 1; ++i){
if (i < tmp->getSize()){
//newData->data[i] = tmp->data[i];
newData->setData(tmp->getData()[i], i);
}
else{
//newData->data[i] = dataToAdd;
newData->setData(dataToAdd, i);
}
}
Try:
for (int i = 0; i < tmp->size; ++i){
newData->data[i] = tmp->data[i]; // you were right here
}
newData->data[tmp->size] = dataToAdd;
And back to something I hinted at earlier:
free(tmp->data);
free(this->data);
Both tmp->data and this->data point to the same memory. To be honest I'm not sure what happens if you free the same memory twice, but I doubt it's good. Regardless, I don't think you want to free it. That would leave this in a broken state.
Recap and fixes
Array2<T> *addData(T dataToAdd)
{
Array2 <T> *newData = new Array2 <T>(this->size + 1);
for (int i = 0; i < this->size; ++i)
{
newData->data[i] = this->data[i];
}
newData->data[this->size] = dataToAdd;
return newData;
};
This version leaves this intact and returns a newData that is one bigger than this. What it doesn't do is add anything to this. Which is goofy for a method named addData.
It also leads to stuff like this:
mydata = myData->addData(data);
which leaks memory. The original mydata is lost without deletion, resulting in a memory leak.
What I think you really need is a lot simpler:
Array2<T> & addData(T dataToAdd)
{
this->data = realloc(this->data, this->size + 1);
this->data[this->size] = dataToAdd;
this->size++;
return *this;
};
realloc effectively allocates a new buffer, copies the old buffer into the new one, and frees the old buffer all in one fell swoop. Groovy.
We then add the new element and increment the count of elements stored.
Finally we return a reference to the object so it can be used in a chain.
Usage can be
myData.addData(data);
myData.addData(data).addData(moredata);
myData.addData(data).printArray();
and if you have operator << support written
std::cout << myData.addData(data) << std::endl;
I'd go back over the new version of Array if I were you. Most of the bugs picked off here are conceptual errors and also apply to it. You might just be getting unlucky and it merely looks like it works. I just read C++ Calling Template Function Error. The posted solutions fixed the immediate problem, but did not touch the underlying memory management problems.
As for the rest of your class, I advice following the link and answering What is The Rule of Three? Because Array2 violates the heck out of it.

Crash when deleting a pointer

I have an assignment to create a PriorityQueue structure and I'm having trouble with this piece of code. When I compile it on my compilator everything's fine, but I tried submitting it to ideone and I get the following error:
"glibc detected *** ./prog: double free or corruption".
I was able to track the part that was giving me this error and I found out that what causes the crash is me trying to delete a pointer at the destructor of my class. The problem is that I don't know why I cant delete it. I don't know a lot about pointers but I thought that if I used new to allocate memory I had to delete it after using it and I think this is what I'm trying to do. Here is my code:
struct PriorityQueue
{
LinkedList queue; LinkNode *it,*node;
int sz;
PriorityQueue(){
sz=0;
queue.head=NULL;
queue.tail=NULL;
it = NULL;
node=NULL;
}
~PriorityQueue(){
if(node != NULL) //this is causing the error.
delete [] node;
if(it != NULL)
delete [] it;
}
int size(){
return sz;
}
void enqueue(int x){
node = new LinkNode(x,NULL,NULL);
if(sz==0){
queue.insert_head(x);
sz++;
}
else{
if(x <= queue.head->value ){
queue.insert_head(x);
sz++;
}
else if( x>= queue.tail->value ){
queue.insert_tail(x);
sz++;
}
else{
it = queue.head;
for(int k=0;k<sz;k++){
if( (x>= it->value) && (x <= it->next->value) ){
node->next= it->next;
node->previous = it;
it->next->previous = node;
it->next = node;
sz++;
break;
}
it=it->next;
}
}
}
}
int dequeue_min(){
int min = queue.remove_head();
sz--;
return min;
}
int dequeue_max(){
int max= queue.remove_tail();
sz--;
return max;
}
};
int main()
{
PriorityQueue pq;
pq.enqueue(4);
pq.enqueue(2);
pq.enqueue(7);
pq.enqueue(-6);
pq.enqueue(0);
cout << pq.dequeue_min() << endl; // debe imprimir -6
cout << pq.dequeue_min() << endl; // debe imprimir 0
pq.enqueue(3);
cout << pq.dequeue_min() << endl; // debe imprimir 2
cout << pq.dequeue_min() << endl; // debe imprimir 3
return 0;
}
Thanks.
it and node point to objects, not arrays.
You cannot use the array form of delete[] on them.
Using delete[] will try to remove a pointer whose object is an array of some sort. There is another type of delete, that allows for the deletion of pointers to single objects. (Hint: it's pretty intuitive)
You are deleting it and node using delete []. They are not arrays. You can only use delete [] syntax on arrays or arrays of your objects. Remember the rule of thumb to use the similar delete and new commands for the same data types. If you have allocated memory by new, delete by delete. If you have allocated memory by new [], delete it by deete [].
It seems that it and node not only point to objects rather than arrays, as Slaks pointed out, it seems they also potentially point to the same thing. As a side note, you don't need to check for null before calling delete[] p or delete p: If the pointer p is null, this expression will have no effect.
It is unrelated to your question but please also note that your priority queue as O(n) (with n being the size) complexity. Typically, when implementing a priority queue you want to get O(log(n)) complexity. The easiest strategy to implement such a priority queue is a d-heap which, conveniently, lives in an array and is actually easier to maintain than your linked list (I think, at least).

C++: Program crash while adding object to custom vector class

I'm working on an email validation program for my cmpsci class and am having trouble with this one part.
What I'm doing is reading a list of valid top level domains from a text file into a vector class I wrote myself (I have to use a custom vector class unfortunately). The problem is that the program reads in and adds the first few domains to the vector all well and fine, but then crashes when it gets to the "org" line. I'm completely stumped why it works for the first few and then crashes.
Also, I have to use a custom string class; that's why I have the weird getline function (so I get the input in a char* for my String constructor). I've tried using the standard string class with this function and it still crashed in the same way so I can rule out the source of the problem being my string class. The whole program is quite large so I am only posting the most relevant parts. Let me know if more code is needed please. Any help would be awesome since I have no clue where to go from here. Thanks!
The ReadTlds function:
void Tld::ReadTlds() {
// Load the TLD's into the vector
validTlds = Vector<String>(0); // Init vector; declaration from header file: "static Vector<String>validTlds;"
ifstream in(TLD_FILE);
while(!in.eof()) {
char tmpInput[MAX_TLD_LENGTH]; // MAX_TLD_LENGTH equals 30
in.getline(tmpInput, MAX_TLD_LENGTH);
validTlds.Add(String(tmpInput)); // Crashes here!
}
}
My custom vector class:
#pragma once
#include <sstream>
#define INIT_CAPACITY 100
#define CAPACITY_BOOST 100
template<typename T> class Vector {
public:
// Default constructor
Vector() {
Data=NULL;
size=0;
capacity=INIT_CAPACITY;
}
// Init constructor
Vector(int Capacity) : size(0), capacity(Capacity) {
Data = new T[capacity];
}
// Destructor
~Vector() {
size=0;
Data = NULL;
delete[] Data;
}
// Accessors
int GetSize() const {return size;}
T* GetData() {return Data;}
void SetSize(const int size) {this->size = size;}
// Functions
void Add(const T& newElement) {
Insert(newElement, size);
}
void Insert(const T& newElement, int index) {
// Check if index is in bounds
if((index<0) || (index>capacity)) {
std::stringstream err;
err << "Vector::Insert(): Index " << index << " out of bounds (0-" << capacity-1 << ")";
throw err.str();
}
// Check capacity
if(size>=capacity)
Grow();
// Move all elements right of index to the right
for(int i=size-1; i>=index; i--)
Data[i+1]=Data[i];
// Put the new element at the specified index
Data[index] = newElement;
size++;
}
void Remove(int index) {
// Check if index is in bounds
if((index<0) || (index>capacity-1)) {
std::stringstream err;
err << "Vector::Remove():Index " << index << " out of bounds (0-" << capacity-1 << ")";
throw err.str();
}
// Move all elements right of index to the left
for(int i=index+1; i<size; i++)
Data[i-1]=Data[i];
}
// Index operator
T& operator [] (int index) const {
// Check if index is in bounds
if((index<0) || (index>capacity-1)) {
std::stringstream err;
err << "Vector operator[]:Index " << index << " out of bounds (0-" << capacity-1 << ")";
throw err.str();
}
return Data[index];
}
// Assignment oper
Vector<T>& operator = (const Vector<T>& right) {
Data = new T[right.GetSize()];
for(int i=0; i<right.GetSize(); i++)
Data[i] = right[i];
size = right.GetSize();
return *this;
}
private:
T *Data;
int size; // Current vector size
int capacity; // Max size of vector
void Grow() {
capacity+=CAPACITY_BOOST;
T* newData = new T[capacity];
for(int i=0; i<capacity; i++)
newData[i] = Data[i];
// Dispose old array
Data = NULL;
delete[] Data;
// Assign new array to the old array's variable
Data = newData;
}
};
The input file:
aero
asia
biz
cat
com
coop
edu
gov
info
int
jobs
mil
mobi
museum
name
net
org <-- crashes when this line is read
pro
tel
travel
The error Visual Studio throws is:
Unhandled exception at 0x5fb04013 (msvcp100d.dll) in Email4.exe: 0xC0000005: Access violation reading location 0xabababbb.
The problem is in your grow function:
void Grow() {
capacity+=CAPACITY_BOOST;
T* newData = new T[capacity];
for(int i=0; i<capacity; i++)
newData[i] = Data[i];
You increase the capacity, but then copy elements that didn't exist in the old array. It should be something like:
void Grow() {
int old_capacity = capacity;
capacity+=CAPACITY_BOOST;
T* newData = new T[capacity];
for(int i=0; i<old_capacity; i++)
newData[i] = Data[i];
You also NULL out Data before deleting it in both Grow and the destructor, which causes a memory leak. In both cases, you really don't need to set it to NULL at all, since there's no change of it being accidentally double-deleted (in Grow it's set to a new pointer immediately, in the destructor the object's lifetime is over). So just
delete[] Data;
alone is fine.
Also I think
if(size>=capacity)
can be:
if(size == capacity)
since size should never be over capacity. That would mean you'd already overflowed the buffer.
Matthew is probably right. Still, there's a valuable lesson to be learned here.
When you hit a problem like this, don't stop walking your code in your ReadTlds function. Keep walking inside the Vector class. Functions like Insert and Grow probably hold the error, but if you don't walk through them, you'll never find it.
Debugging is it's own very special skill. It takes a long time to get it down pat.
edit it's a late night and I misread your code, but I left my post to comment back
Also in the default ctor you do
Data = NULL;
capacity=INIT_CAPACITY;
(EDIT: expanded explanation here)
But never allocate the memory for Data. Shouldn't it be:
Vector() {
Data= new T[INIT_CAPCITY];
size=0;
capacity=INIT_CAPACITY;
}
And remove is missing
--size
EDIT:
Fellow readers help me out here:
Data is of type T* but everywhere else you are assigning and allocating it just like T instead of T* . My C++ days are too long gone to remember whether using a T& actually resolves this.
Also I can't remember that if you have an array of pointers and destruct it, that the dtor for the single instances in the array are destroyed.
Also in the assignment operator, wouldn't you be copying the pinters? so you just have to rely on the fact the the instance where you copyid from is never deleted (because then your objects would be dead too).
hth Mario