Delete keyword c++ - c++

I have a class that has 2 bools and an array of pointers which I allocate on heap.The problem is when it calls the destructor it gives me an error,probably because it deletes too much,I saw it trying to access 0xdddddd and showing me this "Exception thrown: read access violation.
this was 0xDEEEDEEF."
1.How do I use "delete" better,is it because of the operator overload?
2.Also it says that i didn't initialized "QuadTree::childs",why?
class QuadTree {
public:
QuadTree* childs[4];
bool info;
bool parent;
QuadTree() {
for (int i = 0; i < 4; ++i) {
childs[i]=NULL;
}
info = false;
parent = false;
}
~QuadTree() {
for (int i = 0; i < 4; ++i) {
delete childs[i];
}
}
QuadTree& operator=(const QuadTree& tree) {
for (int i = 0; i < 4; ++i) {
childs[i] = new QuadTree;
if (tree.childs[i]->parent == 1) {
childs[i] = tree.childs[i];
}
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
}
return *this;
}
}
So this is the code for adding two trees.I created the overload operator for the next reason,if the node of one tree is white and the other is a parent,i just want to copy the parent.
void addTrees(const QuadTree& tree1, const QuadTree& tree2, QuadTree& end) {
if (tree1.info == 1 || tree2.info == 1) {
end.info = 1;
return;
}
else if (tree1.parent == 1 && tree2.parent == 1) {
end.parent = 1;
for (int i = 0; i < 4; ++i) {
end.childs[i] = new QuadTree;
addTrees(*tree1.childs[i], *tree2.childs[i], *end.childs[i]);
}
}
else if (tree1.parent == 1) {
end.parent = 1;
end = tree1;
}
else if (tree2.parent == 1) {
end.parent = 1;
end = tree2;
}
else {
end.info = 0;
}
}

The line childs[i] = tree.childs[i]; is not doing what you think it is doing.
You are now referencing the memory that they allocated and no longer referencing the memory that you allocated. Whoever tries to delete this memory second will have a bad time.
If you want to copy their child into your recently allocated child you will need to dereference the pointer to operate on the object itself. *childs[i] = *tree.childs[i]

The problem is in your assigmnent operator.
QuadTree& operator=(const QuadTree& tree) {
for (int i = 0; i < 4; ++i) {
childs[i] = new QuadTree;
if (tree.childs[i]->parent == 1) {
childs[i] = tree.childs[i];
}
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
}
return *this;
}
};
In these lines:
if (tree.childs[i]->parent == 1) {
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
childs[i] maybe a nullptr which is ok for assignment but not ok for dereferencing.
And with ->parent you do derefence a nullptr
Please check for nullptr before derefencing.

Related

C++ Bubble sort dynamically allocated array

I wrote a bubble sorting algorithm which sorts a dynamically allocated array using string comparison.
Here is my code:
void AddressBook::bubble_sort_address_book(){
bool swapped = true;
while(swapped){
swapped = false;
for(int i = 0; i < noOfEmployees; i++){
if(employees[i].combined_name() > employees[i+1].combined_name()){
Employee temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
}
}
}
}
My problem is pretty obvious, yet I can not seem to figure out how to solve it: The code sometimes fails on the line (in an undefined manner) :
Employee temp_employee = employees[i+1]
Its pretty obvious because if i is equal to the end of the array, accessing memory with i+1 results in undefined behaviour. However, if I stop the for loop with noOfEmployees-1, this does not happen but the first element is never sorted (obviously).
How can I implement bubble sort properly? It seems as such a trivial task. Am I missing something?
The following simplified version in pure C works fine:
int employees[10]= {3,1,7,6,9,7,1,0,2,6};
int noOfEmployees= 10;
void bubble_sort_address_book(void){
bool swapped = true;
int i;
while(swapped){
swapped = false;
for(i = 0; i < noOfEmployees-1; i++){
if(employees[i] > employees[i+1]){
int temp_employee = employees[i+1];
employees[i+1] = employees[i];
employees[i] = temp_employee;
swapped= true;
}
}
}
}
int main()
{
int i;
bubble_sort_address_book();
for (i=0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}
As you request, the function of variable swapped is to indicate that following a complete pass through the array no swap occurred and so it indicates the array is now sorted.
You can use an explicit bound on the outer loop.
You should also split things out into smaller functions.
bool operator <(Employee const & lhs, Employee const & rhs) {
return lhs.combined_name() < rhs.combined_name();
}
// a.k.a. std::swap
void swap(Employee & lhs, Employee & rhs) {
Employee temp(static_cast<Employee&&>(lhs)); // a.k.a. std::move
lhs = static_cast<Employee&&>(rhs);
rhs = static_cast<Employee&&>(temp);
}
void bubble_sort_impl(Employee * begin, Employee * end) {
for (; end != begin; --end) {
for (Employee * it = begin; it+1 != end; ++it) {
if (*(it+1) < *it) {
swap(*it, *(it+1));
}
}
}
}
// do we really need "bubble_" or "_address_book" in this name?
void AddressBook::bubble_sort_address_book() {
bubble_sort_impl(employees, employees + noOfEmployees);
}
another solution:
#include <iostream>
#include <vector>
using namespace std;
int employees[10] = { 3,1,7,6,9,7,1,0,2,6 };
void bubble_sort_address_book(void) {
bool swapped = true;
int i;
int noOfEmployees = 10;
while (swapped) {
swapped = false;
for (i = 1; i <= noOfEmployees ; i++) {
if (employees[i] > employees[i - 1]) {
int temp_employee = employees[i - 1];
employees[i - 1] = employees[i];
employees[i] = temp_employee;
swapped = true;
}
}
}
}
int main()
{
int i;
int noOfEmployees = 10;
bubble_sort_address_book();
for (i = 0; i<noOfEmployees; i++) {
printf("emp %d= %d\n", i, employees[i]);
}
return 0;
}

Index from address in array of pointers?

The code below a solution to the following requirement:
"Change the representation of Link and List from ยง27.9 without changing the user interface provided by the functions. Allocate Links in an array of Links and have the members: first, last, prev, and next be ints (indices into the array). " - Exercise 6 Chapter 27 - Programming: Principles and Practice Using C++ B. Stroustrup
The interface is inherited from an ordinary implementation of an Intrusive doubly linked list. I've added the bool array (and the associated functions) to keep track of memory:
#include <iostream>
struct Link
{
int next;
int prev;
};
//------------------------------------------------------------------------------------
struct List
{
Link** head;
int first; // points to the current first node
int last;
bool* available;
int list_size;
int get_index()
{
for (int i = 0; i < list_size; ++i)
{
if (available[i] == true)
{
available[i] = false;
return i;
}
}
throw std::bad_alloc("bla bla!\n");
}
List()
{
list_size = 30;
head = new Link*[list_size];
available = new bool[list_size];
first = -1;
last = -1;
for (int i = 0; i < list_size; ++i)
{
available[i] = true;
}
}
void List::push_back(Link* l)
{
if (l == nullptr)
{
throw std::invalid_argument("bla bla!\n");
}
int index = get_index();
head[index] = l;
if (last != -1)
{
head[last]->next = index;
head[index]->prev = last;
}
else
{
first = index;
head[index]->prev = -1;
}
last = index;
head[index]->next = -1;
}
void push_front(Link* l)
{
if (l == nullptr)
{
throw std::invalid_argument("bla bla\n");
}
int index = get_index();
head[index] = l;
if (first != -1)
{
head[first]->prev = index;
head[index]->next = first;
}
else
{
last = index;
head[index]->next = -1;
}
first = index;
head[index]->prev = -1;
}
// index = ptr - base
std::ptrdiff_t index_from_address(Link* l) { return l - head[0]; }
Link* front() const { return head[first]; }
};
//------------------------------------------------------------------------------------
int main()
{
List l;
for (int i = 0; i < 10; ++i)
{
l.push_back(new Link());
}
for (int i = 0; i < 10; ++i)
{
l.push_front(new Link());
}
std::cout <<"first = "<< l.first <<", index = " << l.index_from_address(l.front());
getchar();
}
Expected result:
first = 19, index = 19
Actual result:
first = 19, index = 194
Why?
l - head[0]
Here you compare the values of the two pointers. You let all pointers in the array be default initialized, so their values are indeterminate, and therefore the behaviour of accessing the values is undefined.
You probably intended index_from_address to find the index where a particular pointer object is stored - rather than the object that is pointed to, since the pointed to object is not in the array pointed by head. To do that, you must add a whole bunch of &:
Link*& front() const // return a reference to the pointer object, not a copy
// take a reference to the pointer as an argument, add const for good measure
std::ptrdiff_t index_from_address(Link*& l) const
// compare the addresses of the pointers, rather than values
{ return &l - &head[0]; }

Access Violation Pointer Error

I am implementing my version of the basic String class, however I am running into an issue that I have never seen before and have no idea how to properly debug. My code is pasted below. All functions have their header counterparts. My test is simply creating one object using the convert constructor.
A4String obj1("this");
My problem is I get an Access violation reading location exception thrown. My research has indicated that I may be trying to access memory outside of Visual Studio's allotment. I'm having trouble finding where this pointer error exists though. I have placed breakpoints through every step of the convert constructor and subsequent function calls within however my program doesn't throw the exception until it returns to main, seemingly after my program has executed completely.
#include "A4String.h"
A4String::A4String() {
data = new char[5];
data[0] = '\0';
capacity = 5;
}
A4String::~A4String() {
if (capacity != 0)
delete[] data;
}
//Copy Constructor
A4String::A4String(const A4String &right) {
cout << "copy" << endl;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
}
//Convert Constructor
A4String::A4String(const char *sptr) {
cout << "convert" << endl;
capacity = (strlen(sptr)) + 1;
data = new char[capacity + 1];
strcpy(sptr, data, capacity);
}
//Assignment
A4String& A4String::operator = (const A4String & right) {
//if (capacity != 0) delete[] data;
data = new char[right.capacity + 1];
strcpy(data, right.data, capacity);
capacity = right.capacity;
return *this;
}
//Equivalence
bool A4String::operator == (const A4String &right) const {
return (strcmp(data, right.data)) == 0;
}
int A4String::length() const {
return capacity;
}
void A4String::addChar(char) {
//Not implemented yet
}
string A4String::toString() {
string str = "";
int i = 0;
while (data[i] != '\0') {
str += data[i];
i++;
}
return str;
}
void A4String::strcpy(const char *source, char* destination, int size)
{
for (int i = 0; i < 20; i++)
destination[i] = '\0';
int index = 0;
while (source[index] != '\0')
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
int A4String::strcmp(char *str1, char *str2)
{
if (*str1 < *str2)
return -1;
if (*str1 > *str2)
return 1;
if (*str1 == '\0')
return 0;
return strcmp(str1 + 1, str2 + 1);
return 0;
}
int A4String::strlen( char *s)
{
char *start;
start = s;
while (*s != 0)
{
++s;
}
return s - start;
}
The problem is your A4String::strcpy, the line
for (int i = 0; i < 20; i++)
destination[i] = '\0';
The destination has less than 20 characters, so it crashes.
Use of the hard code number 20 in the A4String::strcpy is not right. I suggest changing it to size.
void A4String::strcpy(const char *source, char* destination, int size)
{
// for (int i = 0; i < 20; i++)
for (int i = 0; i < size; i++)
destination[i] = '\0';
int index = 0;
// Add an additional check here also.
// while (source[index] != '\0' )
while (source[index] != '\0' && index < size)
{
destination[index] = source[index];
index++;
}
destination[index] = '\0';
}
Disclaimer Fixing the above function may not fix your crashing problem even though the use of 20 is most likely crashing your program. In other words, there might be other problems in your code too.

c++ valgrind: Conditional jump or move depends on uninitialised value(s) don't know what to initialize

I've been trying to understand what havn't I initialized in this code and I completely(?) understand what is uninitialized but I don't know how to initialize it.
I am getting the error:
==11931== Conditional jump or move depends on uninitialised value(s)
==11931== at 0x804ABA6: Hashtable<int>::put(int, int) (hash_table.h:169)
==11931== by 0x8048F80: test_put() (hash_table_test.cpp:27)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
==11931== Uninitialised value was created by a heap allocation
==11931== at 0x402ADFC: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==11931== by 0x804A9AE: Hashtable<int>::Hashtable() (hash_table.h:64)
==11931== by 0x8048F62: test_put() (hash_table_test.cpp:26)
==11931== by 0x804A551: main (hash_table_test.cpp:52)
from the valgrind so apparantly I havn't been initializing correctly the c'tor for Hashtable class:
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
the dynamic array is of type Node* which it's private fields are:
bool delete_val;
T element;
int key;
bool default_node;
the class Node is inside the class Hashtable.
how can I initialize dynamicArray?
here's the full code:
#include <string>
#include <iostream>
#include "library2.h"
#include <iterator>
using namespace std;
#ifndef HASH_TABLE_HPP_
#define HASH_TABLE_HPP_
#define DIV 2
//type T must have c'tor, operator !=
template<class T>
class Hashtable {
public:
class Node {
public:
Node(const T t) :
delete_val(false), element(t), key(0), default_node(true) {
}
Node(bool v, const Node& n) :
delete_val(v), element(n.element), key(0), default_node(
n.default_node) {
}
Node(const Node& n) :
delete_val(false), element(n.element), key(n.key), default_node(
n.default_node) {
}
Node() :
delete_val(false), key(0), default_node(true) {
}
bool operator==(const Node* n) {
if (n) {
if (element != n->element || default_node != n->default_node) {
return false;
}
return true;
}
return false;
}
bool operator!=(const Node n) {
if (!(*this == n)) {
return false;
}
return true;
}
bool delete_val;
T element;
int key;
bool default_node;
};
Hashtable() :
ht_keys(2), ht_size(0), dynamicArray(NULL) {
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i].delete_val = false;
dynamicArray[i].key=0;
dynamicArray[i].default_node = false;
}
}
//seriously damaged programming...
Hashtable(Node* array, int HT_keys, int HT_size) :
ht_keys(HT_keys), ht_size(HT_size) {
dynamicArray = new Node[ht_keys];
if (array != NULL) {
for (int i = 0; i < ht_keys; i++) {
dynamicArray[i] = array[i];
}
}
}
Hashtable(const Hashtable& ht) {
if (&ht == this) {
return;
}
ht_keys = ht.ht_keys;
ht_size = ht.ht_size;
dynamicArray = new Node[ht_keys];
for (int i = 0; i < ht.ht_keys; i++) {
this->dynamicArray[i] = ht.dynamicArray[i];
}
}
~Hashtable() {
delete[] this->dynamicArray;
}
Hashtable operator=(const Hashtable& ht) {
Hashtable<T> newHT = ht;
return newHT;
}
//Returns true if some value equal to value exists within the hash table.
bool contains(Node n, int i) {
if (i < 0 || i > ht_keys || !n) {
return false;
}
if (i == ht_keys) {
return false;
}
//make sure that n.delete_val is not set as true.
if (dynamicArray[i]->element == n.element
&& !dynamicArray[i]->delete_val) {
return true;
}
if (dynamicArray[i]->delete_val) {
return contains(n, i + 1);
}
return false;
return true;
}
//Returns true if some key equal to key exists within the hash table.
bool containsKey(int i) {
if (i < 0 || i > ht_keys) {
return false;
}
if (dynamicArray[i]->element && !dynamicArray[i]->delete_val) {
return true;
}
return false;
}
//Returns true if some value equal to value exists within the hash table.
bool containsValue(T e) {
return true;
}
//Returns an enumeration of the values contained in the hash table.
int enumeration() {
return ht_size;
}
//Returns the object that contains the value associated with key.
//If key is not in the hash table, a null object is returned.
Node get(int i) {
if (i >= 0) {
return dynamicArray[i % ht_keys];
}
Node n;
return n;
}
//Returns true if the hash table is empty;
//returns false if it contains at least one key.
bool isEmpty() {
if (ht_size) {
return false;
}
return true;
}
//Returns an enumeration of the keys contained in the hash table.
int keys();
//Inserts a key and a value into the hash table.
//Returns false if key isn't already in the hash table;
//returns true if key is already in the hash table.
bool put(T e, int i) {
if (e && i > 0) {
Node n;
n.default_node = false;
n.delete_val = false;
n.key = i;
n.element = e;
//line 168
for (int j = (i % ht_keys); j < ht_keys; j = ((j + 1) % ht_keys)) { //line 169
if (!dynamicArray[j % ht_keys].element
|| dynamicArray[j % ht_keys].delete_val) {
dynamicArray[j % ht_keys] = n;
ht_size++;
return true;
}else if (i == (j + 1) % ht_keys) {
rehash();
return put(e, i);
}
}
return false;
}
return false;
}
bool put_aux(Node n, int i, Node* Array, int HT_keys) {
for (int j = (i % HT_keys); j < HT_keys; j = ((j + 1) % HT_keys)) {
if (!Array[j % HT_keys].element || Array[j % HT_keys].delete_val) {
Array[j % HT_keys] = n;
return true;
} else if (Array[j % HT_keys].element == n.element) {
return true;
}
}
return false;
}
//Increases the size of the hash table and rehashes all of its keys.
void rehash() {
int old_ht_keys = ht_keys;
ht_keys = DIV * ht_keys;
Node* newArray = new Node[ht_keys];
if (ht_keys > DIV) {
for (int j = 0; j < old_ht_keys; j++) {
put_aux(dynamicArray[j],dynamicArray[j].key,newArray,ht_keys);
}
}
delete[] dynamicArray;
dynamicArray = newArray;
}
//Removes key and its value.
//Returns the value associated with key.
//If key is not in the hash table, a null objecht_sizet is returned.
T remove(int i) {
if (i >= 0 && i < ht_keys) {
Node deleted_node(true, dynamicArray[i % ht_keys]);
dynamicArray[i % ht_keys] = deleted_node;
ht_size--;
return deleted_node.element;
}
return NULL;
}
//Returns the number of entries in the hash table.
int size() {
return this->ht_size;
}
private:
int ht_keys;
int ht_size;
Node* dynamicArray;
};
#endif /* HASH_TABLE_HPP_ */
It seems to be complaining about the line !dynamicArray[j % ht_keys].element (on line 163 of the code you posted; this would be a lot easier if the code you posted matched the code valgrind was using; right now the code you posted is several lines shorter than the code valgrind is using).
You never initialize the element member when you allocate the memory in the constructor. You then attempt to use it here in a conditional statement. valgrind correctly warns you of the problem.

Invalid allocation size. Trying to merge Array Sorted List

I have to develop two functions. One is an application level function that merges two sortedlists implemented using dynamic arrays. The other is the same except its supposed to be a member function. I get invalid allocation size. When I trace the function it successfully returns without an error buy as soon as I reach the original calling code I get the error. Here is the code for both functions.
Application level function:
ArraySortedType& merge(const ArraySortedType& list1, const ArraySortedType& list2)
{
ItemType temp;
ArraySortedType ret, list1Copy=list1, list2Copy=list2;
list1Copy.ResetList();
while (list1Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
list2Copy.ResetList();
while (list2Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
return ret;
}
Member function:
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
Code where I call functions:
ArraySortedType u = merge(s, n);
//ArraySortedType k = merge(s, n);
cout << "Length of u is: " << u.LengthIs() << endl;
// cout << "Length of k is: " << k.LengthIs() << endl;
Even the commented out code doesn't work.
Also there is alot of code for implementing the ArraySortedType that I've left out because I think it's unnecessary. Most of it was already given with the lab. InsertItem was implemented by me and is used quite a bit so I'll include it here:
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
GetNextItem() and ResetList() were already given so they cant be the problem so I'll leave them out but just tell me if they are required.
I've traced both of them and googled quite a bit but this problem has left me scratching my head. Any help would be appreciated.
EDIT:
I guess the implementation of ArraySortedList will be necessary. Here it is. Guess I don't really expect anyone to actually go through it though:
//ArraySortedType.cpp
#include "ArraySortedType.h"
ArraySortedType::ArraySortedType (int max_items)
{
length =0;
MAX_ITEMS = max_items;
currentPos =-1;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
ArraySortedType::~ArraySortedType()
{
delete [] info;
info = NULL;
}
void ArraySortedType::ResetList ( )
{
currentPos = -1;
}
bool ArraySortedType::IsFull ( ) const
{
if(length == MAX_ITEMS)
{
try
{//Check if memory allocation is fine
ItemType * temp = new ItemType[2*MAX_ITEMS];
delete [] temp;
return false;
}
catch(std::bad_alloc exception)
{
return true;
}
}
return false;
}
bool ArraySortedType::IsEmpty () const {
return (length==0);
}
int ArraySortedType:: LengthIs () const {
return length;
}
Error_Code ArraySortedType::DeleteItem ( ItemType item ) {
int location = 0;
while ((item.ComparedTo(info[location]) != EQUAL ) && location < length)
location++;
if (location == length) return Fail;
info[location] = info[length - 1];
length--;
return Success;
}
Error_Code ArraySortedType::GetNextItem (ItemType& item) {
currentPos++;
if( currentPos == length ) return Fail;
item = info[currentPos] ;
return Success;
}
ArraySortedType::ArraySortedType(const ArraySortedType & ust)
{
MAX_ITEMS =ust.MAX_ITEMS;
length=ust.length;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
for(int i=0;i<length; i++)
info[i] = ust.info[i];
currentPos=ust.currentPos;
}
ArraySortedType& ArraySortedType::operator=(const ArraySortedType & ust)
{
if(this == &ust) return *this;
if(MAX_ITEMS !=ust.MAX_ITEMS)
{
delete [] info;
MAX_ITEMS = ust.MAX_ITEMS;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
currentPos=ust.currentPos;
length=ust.length;
for(int i=0;i<length; i++)
info[i] = ust.info[i];
return *this;
}
//Assumes that an employee has unique ID
bool ArraySortedType::operator==(const ArraySortedType & ust)
{
if(this == &ust) return true;
if(length!=ust.length) return false;
if(currentPos!=ust.currentPos) return false;
for(int i=0;i<length; i++)
if(info[i].ComparedTo(ust.info[i])!=EQUAL) return false;
return true;
}
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
Error_Code ArraySortedType::RetrieveItem (ItemType& item , bool& found)
{
found = false;
int front = 0, back = length - 1, midpoint=(length-1)/2;
while (front<=back)
{
switch (info[midpoint].ComparedTo(item))
{
case EQUAL:
item = info[midpoint];
found = true;
break;
case LESS:
front = midpoint + 1;
break;
case GREATER:
back = midpoint - 1;
break;
}
if (found)
break;
midpoint = ((back - front) / 2 + front);
}
return Fail;
}
Error_Code ArraySortedType::Delete(ItemType startKey, ItemType endKey)
{
bool startFound = false, endFound = false;
int numberDeleted=0, startLocation;
bool deleting = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
deleting = true;
startFound = true;
}
if (deleting)
numberDeleted++;
if (info[i].ComparedTo(endKey) == EQUAL)
{
deleting = false;
endFound = true;
}
}
if (!(startFound || endFound))
return Fail;
length -= numberDeleted;
for (int i = startLocation; i < length; i++)
info[i] = info[i + startLocation];
return Success;
}
ArraySortedType ArraySortedType::RetrieveItemsInRange(ItemType startKey, ItemType endKey)
{
ArraySortedType r;
bool startFound = false, endFound = false;
int numberDeleted = 0, startLocation;
bool retrieving = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
retrieving = true;
startFound = true;
}
if (retrieving)
r.InsertItem(info[i]);
if (info[i].ComparedTo(endKey) == EQUAL)
{
retrieving = false;
endFound = true;
}
}
return r;
}
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
ItemType is defined as a class Employee. I really hope I don't have to include it here as well. The class Employee has a compareTo class defined as follows:
RelationType Employee::ComparedTo(const Employee & e)
{
if(eid < e.eid) return LESS;
else if(eid == e.eid) return EQUAL;
else return GREATER;
}
There is a an enum called relation type that has values LESS, EQUAL and GREATER.