Problem when trying to access struct object inside of array of structs - c++

I am having trouble trying to push an element into my queue and I cannt figure out what is wrong. I have an own-defined data type and I am pretty sure I am not trying to acces memory that has not been allocated or any other such-related scenarios.
Queue.h
typedef int TElem
//...
struct NodeDLLA {
TElem data;
int prev;
int next;
};
class Queue
{
//...
}
Queue.cpp
Queue::Queue() {
cap = 105;
len = 0;
head = -1;
tail = -1;
NodeDLLA* nodes = new NodeDLLA[cap];
nodes[0].prev = -1;
nodes[0].next = 1;
for (int i = 1; i < cap - 1; i++)
{
nodes[i].prev = i - 1;
nodes[i].next = i + 1;
}
nodes[cap - 1].prev = cap - 2;
nodes[cap - 1].next = -1;
firstEmpty = 0;
}
void Queue::push(TElem elem) {
if (firstEmpty == -1)
{
//resize array...
}
cout << "check\n";
cout << firstEmpty <<'\n';
nodes[firstEmpty].data = elem; // here is the problem.
cout << "check2\n";
// "check" is shown in the console terminal, but "check2" is not.
// firstEmpty is zero, thus there should be no problem of trying to access "illegal memory area"
// ... rest of code
}
ShortTest.cpp
#include "ShortTest.h"
#include "Queue.h"
#include <assert.h>
#include<iostream>
using std::cout;
void testAll() {
Queue q;
assert(q.isEmpty() == true);
q.push(5);
cout << "So far so good" << '\n';
/*
q.push(1);
q.push(10);
assert(q.isEmpty() == false);
assert(q.top() == 5);
assert(q.pop() == 5);
assert(q.top() == 1);
assert(q.pop() == 1);
assert(q.top() == 10);
assert(q.pop() == 10);
assert(q.isEmpty() == true);
*/
}
main.cpp
#include "Queue.h"
#include "ShortTest.h"
int main()
{
testAll();
return 0;
}
Console output:
check
Expected output:
check
check2
So far so good

Related

Circular Queue That has a display function that displays even numbers only

hi so i have this circular queue c++ program i need its display function only displays even inserted numbers only can someone here help please here's the code
i need a way that this program only displays even numbers only i'v been trying to use the %2==0 on some location that might make sense but mostly i get them wrong or empty
.
.
.
.
.
.
#include <iostream>
using namespace std;
int cqueue[5];
int front = -1, rear = -1, n=5;
void insertCQ(int val) {
if ((front == 0 && rear == n-1) || (front == rear+1)) {
cout<<"Queue Overflow \n";
return;
}
if (front == -1) {
front = 0;
rear = 0;
} else {
if (rear == n - 1)
rear = 0;
else
rear = rear + 1;
}
cqueue[rear] = val ;
}
void deleteCQ() {
if (front == -1) {
cout<<"Queue Underflow\n";
return ;
}
cout<<"Element deleted from queue is : "<<cqueue[front]<<endl;
if (front == rear) {
front = -1;
rear = -1;
} else {
if (front == n - 1)
front = 0;
else
front = front + 1;
}
}
void displayCQ() {
int f = front, r = rear;
if (front == -1) {
cout<<"Queue is empty"<<endl;
return;
}
cout<<"Queue elements are :\n";
if (f <= r) {
while (f <= r){
cout<<cqueue[f]<<" ";
f++;
}
} else {
while (f <= n - 1) {
cout<<cqueue[f]<<" ";
f++;
}
f = 0;
while (f <= r) {
cout<<cqueue[f]<<" ";
f++;
}
}
cout<<endl;
}
int main() {
int ch, val;
cout<<"1)Insert\n";
cout<<"2)Delete\n";
cout<<"3)Display\n";
cout<<"4)Exit\n";
do {
cout<<"Enter choice : "<<endl;
cin>>ch;
switch(ch) {
case 1:
cout<<"Input for insertion: "<<endl;
cin>>val;
insertCQ(val);
break;
case 2:
deleteCQ();
break;
case 3:
displayCQ();
break;
case 4:
cout<<"Exit\n";
break;
default: cout<<"Incorrect!\n";
}
} while(ch != 4);
return 0;
}
Here's a quick example using std::queue:
#include <iostream>
#include <queue>
int main()
{
// This deque is declared just to more easily instantiate the queue
std::deque<int> deck{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::queue<int> q{deck};
while (!q.empty()) {
if (q.front() % 2 == 0) {
std::cout << q.front() << ' ';
}
q.pop();
}
std::cout << '\n';
}
You were on the right path using mod 2, but everything about your "queue" is not correct. To put it simply, you have not written a queue, and definitely not a circular queue.
Queues are FIFO data structures; first in, first out. Think of it like a tunnel. I will only add elements to one end, and I will only remove elements from the other. Everything in the middle does not matter, except to know the size of the queue. This means that the only visible elements are the first and last. If I want to see the second element of the queue, I must remove the first element.
The code you've written treats your array like a list instead where you have free access to all elements.
It's better to write an actual queue class, and I would hope that if you're writing data structures, that you are able to write a class.
Here's an extremely basic queue class that exhibits the behavior you are asking about. There is nothing circular about it. The word circular implies that your queue should be implemented with a circular linked list and not an array. It's worth noting that it requires at least C++11, but that really shouldn't be a problem today.
IMPORTANT
This code leaves out a lot of necessary error-checking. For example, back() will likely lead to undefined behavior if called on an empty queue, among other things. This was intentional to avoid a flat-out copy/paste being employed because cheating on homework is bad.
#include <array>
#include <iostream>
namespace Q {
class queue {
public:
int &front() { return m_arr[0]; }
int &back() { return m_arr[m_size - 1]; }
void push(int val) {
if (m_size < 5) {
m_arr[m_size] = val;
++m_size;
}
}
// Shifts entire array one to the left
void pop() {
if (m_size > 0) {
for (int i = 1; i < m_size; ++i) {
m_arr[i - 1] = m_arr[i];
}
--m_size;
}
}
bool empty() const { return m_size == 0; }
private:
std::array<int, 5> m_arr = {0};
int m_size = 0;
};
}; // namespace Q
int main() {
Q::queue q;
for (int i = 1; i <= 5; ++i) {
q.push(i);
}
while (!q.empty()) {
if (q.front() % 2 == 0) {
std::cout << q.front() << ' ';
}
q.pop();
}
std::cout << '\n';
}

Calling two Queue class function in a loop

I have problem with this code of mine. Whenever i call two function of the class, and in those class, there is if-else statement, and print the output on screen, it will only run the if clause of the two functions and not the else. How can i fix this?
For example:
This is my Queue.h file:
#ifndef QUEUE_H
#define QUEUE_H
class Queue {
private:
//private variables
int arr_size;
char *arr;
int head;
int tail;
int count;
public:
Queue(int); //constructor
//functions
int enqueue(char);
int dequeue(char&);
};
#endif
This is my Queue.cpp file:
#include <iostream>
#include "Queue.h"
using namespace std;
Queue::Queue(int size) {
//initializing
arr_size = size;
arr = new char[size];
for (int i = 0; i < arr_size; i++) {
arr[i] = NULL;
}
head = 0;
tail = 0;
count = 0;
}
int Queue::enqueue(char value) {
if (count<arr_size) //if array is not full, execute below
{
arr[tail++] = value; //pass value of first-to-last element in array
count++; //counting the input value
cout << "\nEnqueue Value: "<< arr[tail-1];
return 0;
}
else {
tail = 0;
cout << "\nArray is full. Value cannot be write: " << value;
return -1;
}
}
int Queue::dequeue(char &read_val) {
if (count !=0) { //if array has elements, execute below
read_val = arr[head]; //pass-by-reference the value of first-to-last element in array to parameter of function
cout <<"\nDequeue Value: "<<read_val;
arr[head] = NULL;
count--;
if (head++ == arr_size) {
head = 0;
}
return 0;
}
else if (count ==0) {
cout << "\nArray is empty. Cannot be dequeue";
return -1;
}
}
And this is what my Source file:
#include "Queue.h"
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Please enter the desired size of the array: ";
cin >> n;
char read_val = NULL;
Queue myqueue(n);
char arr[] = "Hello World, this is ELEC3150";
int size = sizeof(arr)-1;
int count = 0;
for (int i = 0; i < 5; i++) {
myqueue.enqueue(arr[count]);
count++;
myqueue.dequeue(read_val);
}
If i enter the size of the array to be less than 5, it must print the error message saying the array is full in the enqueue function and the array is empty in the dequeue function but did not.

Discrete Event Simulation Algorithm debug

I am working on a discrete event simulation program in C++. My output is completely incorrect but all the output values are pretty close to the correct output. I have tried debugging my algorithm but I couldn't find any errors. Below is my main algorithm for the simulation.
I implemented the event priority queue using a min heap and array. I am not allowed to use any STL libraries. The FIFO queue used in the code is a linked list. When I print the event time at the top of the priority queue, the events are not always getting passed in ascending order (which I think is how event priority queues are supposed to work) and I do not understand why. The ascending order is breached mostly around event completion times. Please help!
#include <iostream>
#include <fstream>
#include "PQueue.h"
#include "SPqueue.h"
#include "LinkedList.h"
using namespace std;
int serverCount; //number of servers
Spqueue spq; //priority queue for servers
Pqueue pq; //priority queue for events
LinkedList list; //FIFO queue to put arriving events in
double totalTime; //variables for statistics calculation
double timeNow;
double totalWait;
int ql;
int qlength = 0;
double totalQlength;
int time = 0;
bool available(); //checks availability of servers
int main() {
ifstream fin;
fin.open("Sample2.txt");
if (!fin.good())
cerr << "Couldn't find file/corrupted file" << endl;
fin >> serverCount; //reads number of servers and efficiency
//from file
for (int i = 0; i < serverCount; i++) {
server s;
fin >> s.effi;
s.status = true;
s.count = 0;
spq.insert(s);
}
//reads first event from file
event e;
fin >> e.eventTime;
fin >> e.serviceTime;
e.eventType = -1;
pq.insert(e);
int i = 1;
//while priority queue is not empty
while (!pq.isEmpty()) {
timeNow = pq.getArrivalTime(1);
while (time < pq.getArrivalTime(1)) {
totalQlength = totalQlength + list.getLength();
time++;
}
//get event from priority queue
if (pq.getServer(1) == -1) { //if arrival event, add to FIFO queue
list.AddTail(pq.getArrivalTime(1), pq.getServiceTime());
if (list.getLength() > qlength) {
qlength = list.getLength();
}
//read next arrival event from file
if (!fin.eof()) {
event e;
fin >> e.eventTime;
fin >> e.serviceTime;
e.eventType = -1;
pq.insert(e);
i++;
}
}
else //must be customer complete event
{
spq.setIdle(pq.getServer(1)); //set the server to idle
}
pq.deleteMin(); //remove the evnt from priority queue
//if FIFO queue is not empty and servers are available
//process event
if ((list.isEmpty() == false) && (available() == true)) {
list.getHead();
int s = spq.getMin();
spq.setBusy(s); //set server to busy
spq.incrementCustNumber(s); //increment number of customers
//served
double waitTime = timeNow - list.getHead().arrivalTime;
totalWait = totalWait + waitTime;
double serviceT = spq.getEffi(s) * list.getHead().serviceTime;
double eventT = list.getHead().arrivalTime +serviceT;
event e2;
e2.eventTime = eventT;
e2.serviceTime = list.getHead().serviceTime;
e2.eventType = s;
pq.insert(e2); //add customer complete event to the priority
//queue
list.RemoveHead(); //remove head from FIFO
}
totalTime = pq.getArrivalTime(1);
}
fin.close();
return 0;
}
bool available() {
bool ava = false;
for (int i = 1; i <= serverCount; i++) {
if (spq.getStatus(i) == true) {
ava = true;
break;
}
}
return ava;
}
Below is the priority queue implementation:
#include <iostream>
#include <fstream>
#include "PQueue.h"
using namespace std;
Pqueue::Pqueue() {
inde = 0; //length of heap
}
void Pqueue::insert(event i) { //inserts new element into the heap array and maintains min heap property
inde++;
pqueue[inde] = i;
siftup(inde);
}
int Pqueue::getServer(int i) {
return pqueue[i].eventType;
}
void Pqueue::siftup(int i) { //shifts element up to the correct position in the heap
if (i == 1)
return;
int p = i / 2;
if (pqueue[p].eventTime > pqueue[i].eventTime)
{
swap(pqueue[i], pqueue[p]);
siftup(p);
}
}
void Pqueue::deleteMin() { //removes element at the root of the heap
swap(pqueue[inde], pqueue[1]);
inde--;
siftdown(1);
}
void Pqueue::siftdown(int i) { //shifts element to its position in the min heap
int c = i * 2;
int c2 = (i * 2) + 1;
if (c > inde) return;
int in = i;
if (pqueue[i].eventTime > pqueue[c].eventTime)
{
in = c;
}
if ((c2 < inde) && (pqueue[i].eventTime > pqueue[c2].eventTime))
{
in = c2;
}
if (pqueue[c].eventTime < pqueue[c2].eventTime) {
in = c;
}
if (in != i) {
swap(pqueue[i], pqueue[in]);
siftdown(in);
}
}
void Pqueue::swap(event& i, event& j) {
event temp;
temp = i;
i = j;
j = temp;
}
bool Pqueue::isEmpty() { //checks if the priority queue is empty
if (inde == 0) return true;
else
return false;
}
double Pqueue::getArrivalTime(int i) {
return pqueue[i].eventTime;
}
double Pqueue::getServiceTime() {
return pqueue[1].serviceTime;
}
There are five servers with varying efficiency. The most efficient idle server is to be used. For this, I sorted the array of servers efficiency wise in the beginning.
#include <iostream>
#include <fstream>
#include "SPqueue.h"
using namespace std;
Spqueue::Spqueue() {
inde = 0;
}
void Spqueue::insert(server i) { //inserts new element into the array
inde++;
spqueue[inde] = i;
}
void Spqueue::heapify(int n, int i)
{
int largest = i; // Initialize largest as root
int l = 2 * i; // left = 2*i + 1
int r = 2 * i +1; // right = 2*i + 2
// If left child is larger than root
if (l < n && spqueue[l].effi > spqueue[largest].effi)
largest = l;
// If right child is larger than largest so far
if (r < n && spqueue[r].effi > spqueue[largest].effi)
largest = r;
// If largest is not root
if (largest != i)
{
swap(spqueue[i], spqueue[largest]);
// Recursively heapify the affected sub-tree
heapify(n, largest);
}
}
void Spqueue::heapSort()
{
// Build heap (rearrange array)
for (int i = inde / 2 - 1; i > 0; i--)
heapify(inde, i);
// One by one extract an element from heap
for (int i = inde - 1; i > 0; i--)
{
// Move current root to end
swap(spqueue[1], spqueue[i]);
// call max heapify on the reduced heap
heapify(i, 1);
}
}
void Spqueue::swap(server& i, server& j) {
server temp;
temp = i;
i = j;
j = temp;
}
int Spqueue::getMin() { //iterates to the next available server in the sorted list of servers
int i = 0;
while (i <=20){
if (spqueue[i].status == true)
{
return i;
}
else
{
i++;
}
}
}
bool Spqueue::getStatus(int i) {
return spqueue[i].status;
}
void Spqueue::setBusy(int i) {
spqueue[i].status = false;
}
void Spqueue::addServiceTime(int i,double s) {
spqueue[i].busyTime = spqueue[i].busyTime + s;
}
double Spqueue::getTotalServiceTime(int i) {
return spqueue[i].busyTime;
}
void Spqueue::setIdle(int i) {
spqueue[i].status = true;
}
double Spqueue::getEffi(int i) {
return spqueue[i].effi;
}
void Spqueue::incrementCustNumber(int i) {
spqueue[i].count++;
}
int Spqueue::getCount(int i) {
return spqueue[i].count;
}
And the following function is supposed to return the most efficient server.
int Spqueue::getMin() { //iterates to the next available server in
the already sorted array
int i = 0;
while (i <=20){
if (spqueue[i].status == true)
{
return i;
}
else
{
i++;
}
}
}
Your priority queue implementation of siftdown has some problems.
void Pqueue::siftdown(int i) { //shifts element to its position in the min heap
int c = i * 2;
int c2 = (i * 2) + 1;
// *** Possible bug
// *** I think that if c == inde, then c is indexing beyond the current queue
if (c > inde) return;
int in = i;
if (pqueue[i].eventTime > pqueue[c].eventTime)
{
in = c;
}
if ((c2 < inde) && (pqueue[i].eventTime > pqueue[c2].eventTime))
{
in = c2;
}
// ***************
// ** Bug here
if (pqueue[c].eventTime < pqueue[c2].eventTime) {
in = c;
}
if (in != i) {
swap(pqueue[i], pqueue[in]);
siftdown(in);
}
}
First, I think you want to test c1 >= inde. Also, when you're checking to see if pqueue[c].eventTime < pqueue[c2].eventTime, you do so without making sure that c2 is within bounds.
I find the following to be a more clear and succinct way to do things:
// find the smallest child
int in = c;
if (c2 < inde && pqueue[c2] < pqueue[c])
{
in = c2;
}
if (pqueue[in] < pqueue[i]) {
swap(pqueue[i], pqueue[in]);
siftdown(in);
}

Inserting Values of Array to Ordered Linked List C++

Background
Creating a dice game where the dice roll value should be stored in a Linked List.
Question
How should an implementation of Linked List be completed in C++? '
Example (What I have tried using struct instead of class)
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
struct Score {
int d1;
int d2;
int total;
int totals[13];
int value;
struct Score * next;
}
score_dice1, score_dice2, score_total, score_totals;
struct Score * ordered_insert(struct Score * , struct Score * );
int dice = 2;
void Randomize() {
srand((unsigned) time(NULL));
}
int Random(int Max) {
return (rand() % Max) + 1;
}
int main(int argc, char * argv[]) {
struct Score * myList = NULL;
if (argc == 2) {
int dice_rolls;
dice_rolls = atoi(argv[1]);
Randomize();
for (dice = 2; dice <= 12; dice++)
score_totals.totals[dice] = 0;
for (dice = 0; dice < dice_rolls; dice++) {
score_dice1.d1 = Random(6);
score_dice2.d2 = Random(6);
score_total.total = score_dice1.d1 + score_dice2.d2;
score_totals.totals[score_total.total]++;
}
for (dice = 1; dice <= 13; dice++) {
printf("%i %i\n\r", dice, score_totals.totals[dice]);
}
} else {
std::cout << "How many times should we roll the dice?" << '\n' <<
"One number please" << '\n';
}
return 0;
}
You probably want to use the STL, and include the std::list class. You should look at the methods for that class. I will show you how using the std::vector class.
Suppose you want to place the following into the list,
struct roll_t {
int dice1; //value of dice1
int dice2; //value of dice2
int total; //total of dice1+dice2
roll_t() dice1(0), dice2(0), total(0) { }
roll_t(int d1, int d2) : dice1(d1), dice2(d2), total(d1+d2) { };
};
Here is a C++ list reference
Here is an example with explanation
But, let me also add an example here,
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
vector<roll_t> dv;
roll_t rolls[13+1];
//suppose you have initialized totals[] here...
for( ndx=1; ndx<=12; ++ndx ) {
rolls[ndx] = roll_t.new(random(6),random(6));
}
//move totals to vector (convert to list left as exercise for poster)
int ndx;
for( ndx=1; ndx<=12; ++ndx ) {
dv.push_back(rolls[ndx]);
}
//traverse vector (convert to list, you will need iterator)
cout << "Loop by index:" << endl;
for(ndx=0; ndx < dv.size(); dv++)
{
cout << "["<<ndx<<"]"
<< dv[ndx].dice1 <<','<< dv[ndx].dice2 <<','<< dv[ndx].total << endl;
}
}
The above uses the STL, but maybe this question is for a class? And you need to roll your own linked list? I have linked to some stackoverflow answers,
I built one of those,
Trying to make linkedlist in C
Here is a description of single-linked list,
Singly-list insert to end of list
Here is a basic C++ dice game,
Basic C++ Dice game
Here is an explanation of how to sort a linked list by moving pointers,
Trying to Sort a Linked List only by Manipulating Pointers
Those should help.
Answer
Use a class to create the Linked List logic.
Example
linklist.h
#pragma once
#ifndef LINKLIST_H
#define LINKLIST_H
#include <iostream>
using namespace std;
class linklist {
private:
struct node {
int data;
node * link;
}* p;
public:
linklist();
void append(int num);
void add_as_first(int num);
void addafter(int c, int num);
void del(int num);
void display();
int count();
~linklist();
};
linklist::linklist() {
p = NULL;
}
void linklist::append(int num) {
node * q, * t;
if (p == NULL) {
p = new node;
p -> data = num;
p -> link = NULL;
} else {
q = p;
while (q -> link != NULL)
q = q -> link;
t = new node;
t -> data = num;
t -> link = NULL;
q -> link = t;
}
}
void linklist::add_as_first(int num) {
node * q;
q = new node;
q -> data = num;
q -> link = p;
p = q;
}
void linklist::addafter(int c, int num) {
node * q, * t;
int i;
for (i = 0, q = p; i < c; i++) {
q = q -> link;
if (q == NULL) {
cout << "\nThere are less than " << c << " elements.";
return;
}
}
t = new node;
t -> data = num;
t -> link = q -> link;
q -> link = t;
}
void linklist::del(int num) {
node * q, * r;
q = p;
if (q -> data == num) {
p = q -> link;
delete q;
return;
}
r = q;
while (q != NULL) {
if (q -> data == num)
{
r -> link = q -> link;
delete q;
return;
}
r = q;
q = q -> link;
}
cout << "\nElement " << num << " not Found.";
}
void linklist::display() {
node * q;
cout << endl;
for (q = p; q != NULL; q = q -> link)
cout << endl << q -> data;
}
int linklist::count() {
node * q;
int c = 0;
for (q = p; q != NULL; q = q -> link)
c++;
return c;
}
linklist::~linklist() {
node * q;
if (p == NULL)
return;
while (p != NULL) {
q = p -> link;
delete p;
p = q;
}
}
#endif
main.cc
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <list>
#include <vector>
#include "linklist.h"
struct score {
int d1;
int d2;
int total;
int totals[13];
}
score_dice1, score_dice2, score_total, score_totals;
int dice = 2;
void Randomize() {
srand((unsigned) time(NULL));
}
int Random(int Max) {
return (rand() % Max) + 1;
}
int main(int argc, char * argv[]) {
linklist ll;
if (argc == 2) {
int dice_rolls;
dice_rolls = atoi(argv[1]);
Randomize();
for (dice = 2; dice <= 12; dice++)
score_totals.totals[dice] = 0;
for (dice = 0; dice < dice_rolls; dice++) {
score_dice1.d1 = Random(6);
score_dice2.d2 = Random(6);
score_total.total = score_dice1.d1 + score_dice2.d2;
score_totals.totals[score_total.total]++;
}
for (dice = 1; dice <= 13; dice++) {
ll.append(score_totals.totals[dice]);
std::cout << ll.count() << '\n';
ll.display();
}
} else {
std::cout << "How many times should we roll the dice?" << '\n' <<
"One number please" << '\n';
}
return 0;
}

C++ pointer "losing" its value

As an exercise (largely an exercise in trying to write something using pointers), I'm writing a cache simulation, specifically of the pseudo least recently used system from the old 486. I'm getting an "Access violation reading location" error on the line:
int min = treeArray[set]->root->findPLRU();
Initially the treeArray seems to be initialised properly (if I pause the program at the start and take a look, it's all as should be), but when the programme breaks and I delve in to examine things the root of the tree in question isn't defined.
I feel it's quite probable that I'm making some sort of very elementary pointer mistake, which is causing the pointer to the node to be "lost" somewhere, but I've no clue what it might be. Is there something in particular I need to do to "hold on" to a pointer value?
#include "stdafx.h"
#include "stdlib.h"
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <io.h>
#include "main.h"
//char fn[80]; // trace filename
int tf; // trace file
trace buf[BUFSZ / sizeof(trace)]; // buffer SIZE
int LRUHits = 0;
int pLRUHits = 0;
int randomHits = 0;
int height;
int cachelinenumber;
//log2 helper function
int log2(int n)
{
int i = 0;
while (n)
{
n = n >> 1;
i++;
}
return i - 1;
}
class CacheLine{
public:
int tag;
int access;
CacheLine();
};
class Cache;
class Node{
public:
bool goRight;
Node* left;
Node* right;
int leftCacheLine;
int rightCacheLine;
Node(int depth) // constructor
{
goRight = false;
if (depth < height - 1)
{
left = new Node(depth + 1);
right = new Node(depth + 1);
leftCacheLine = -1;
rightCacheLine = -1;
}
else
{
leftCacheLine = cachelinenumber;
cachelinenumber++;
rightCacheLine = cachelinenumber;
cachelinenumber++;
}
//printf("Depth: %d, Height: %d, Left: %d, Right: %d\n", depth, height, leftCacheLine, rightCacheLine);
}
~Node()
{
delete left;
delete right;
}
int findPLRU()
{
if (leftCacheLine < 0 || rightCacheLine < 0)
{
if (goRight)
{
goRight = false;
return right->findPLRU();
}
else
{
goRight = true;
return left->findPLRU();
}
}
else
{
if (goRight)
{
goRight = false;
return rightCacheLine;
}
else
{
goRight = true;
return leftCacheLine;
}
}
}
};
class Tree{
public:
Node* root;
Tree()
{
root = new Node(0);
}
~Tree()
{
delete root;
}
};
//cache class
class Cache
{
public:
CacheLine *cache;
int l, k, n, replacementPolicy;
int log2l, log2n;
int access;
Tree** treeArray;
//constructor
Cache(int ll, int kk, int nn, int _replacementPolicy)
{
l = ll;
k = kk;
n = nn;
replacementPolicy = _replacementPolicy;
log2l = log2(l);
log2n = log2(n);
cache = (CacheLine*)malloc(sizeof(CacheLine)*k*n);
for (int i = 0; i < k*n; i++)
{
cache[i].tag = 0x80000000;
cache[i].access = 0;
}
if (replacementPolicy == 1)
{
cachelinenumber = 0;
treeArray = new Tree*[n];
for (int i = 0; i < n; i++)
{
treeArray[i] = new Tree();
}
}
access = -1;
}
//destructor
~Cache()
{
free(cache);
}
//test for hit
void hit(int a)
{
access++;
int set = (a >> log2l) & (n - 1);
int tag = a >> (log2n + log2l);
CacheLine* c = &cache[set*k];
for (int i = 0; i < k; i++)
{
if (c[i].tag == tag)
{
c[i].access = access;
if (replacementPolicy == 0)
LRUHits++;
else if (replacementPolicy == 1)
pLRUHits++;
else if (replacementPolicy == 2)
randomHits++;
break;
}
}
if (replacementPolicy == 0) //LRU
{
int min = 0;
int minv = c[0].access;
for (int i = 1; i < k; i++)
{
if (c[i].access < minv)
{
minv = c[i].access;
min = i;
}
}
c[min].tag = tag;
c[min].access = access;
}
else if(replacementPolicy == 1) // pseudoLRU
{
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
}
else // random
{
srand(clock());
int randomNumber = rand()%k;
c[randomNumber].tag = tag;
c[randomNumber].access = access;
}
return;
}
};
void analyse (int l, int k, int n)
{
height = log2(k) + 1;
char fn[] = "ico0.trace";
if ((tf = open(fn, _O_RDONLY | _O_BINARY )) == -1) {
printf("unable to open file %s\n", fn);
exit(0);
}
LRUHits = 0;
pLRUHits = 0;
randomHits = 0;
Cache *cache0 = new Cache(l, k, n, 0); // LRU
Cache *cache1 = new Cache(l, k, n, 1); // pseudoLRU
Cache *cache2 = new Cache(l, k, n, 2); // random
int bytes, word0, a, type, burstcount;
int hits = 0;
int tcount = 0;
while (bytes = read(tf, buf, sizeof(buf)))
{
for (int i = 0; i < bytes / (int) sizeof(trace); i++, tcount++)
{
word0 = buf[i].word0;
a = (word0 & ADDRESSMASK) << 2;
type = (word0 >> TYPESHIFT) & TYPEMASK;
burstcount = ((word0 >> BURSTSHIFT) & BURSTMASK) + 1;
cache0->hit(a);
cache1->hit(a);
cache2->hit(a);
}
}
printf("Hits: %d Total: %d\n", LRUHits, tcount);
printf("Hits: %d Total: %d\n", pLRUHits, tcount);
printf("Hits: %d Total: %d\n\n\n", randomHits, tcount);
delete cache0;
delete cache1;
delete cache2;
}
int _tmain(int argc, _TCHAR* argv[])
{
//analyse(16, 1, 8);
analyse(16, 2, 512);
//analyse(16, 4, 256);
//analyse(16, 8, 128);
//analyse(16, 1024, 1);
_getch();
return 0;
}
Your question hasn't yet been pounced upon, probably because your code still doesn't compile since you've not provided main.h.
And even then it would annoy most folks trying to help you because you make no mention of the ico0.trace file that is required to prevent the code from immediately exiting.
You say int min = treeArray[set]->root->findPLRU(); access violates.
1) the value of set can never exceed the size n of your treeArray since you & n-1 the range of input values.
2) since your ~Tree() destructor is never called there will always be a treeArray[set]->root
3) since you *always create new left & right nodes whenever leftCacheLine = -1 or rightCacheLine = -1 it cannot be due to recursive findPLRUs
So, the pointer to the node is not being "lost" somewhere; it is being stomped on.
Try replacing:
int min = treeArray[set]->root->findPLRU();
c[min].tag = tag;
c[min].access = access;
with:
int min = treeArray[set]->root->findPLRU();
if (min >= k*n)
{
printf("ook\n");
}
else
{
c[min].tag = tag;
c[min].access = access;
}
and I think you will discover what's doing the stomping. ;)