I can't understand why theory and implementation of CRC not indentical? I mean in implementations I find first perform bitshift and then xor. But first bit will not be xored. And in explanation xor starting from first bit.
Here my code for CRC4
public enum CRC4_POLY
{
CRC4 = 0x0B //1011
};
public class CRC4Calc
{
private byte[] table = new byte[16];
public byte Checksum(params byte[] val)
{
if (val == null)
throw new ArgumentNullException("val");
byte c = 0;
foreach (byte b in val)
{
c = table[c ^ b];
}
return c;
}
public byte[] Table
{
get
{
return this.table;
}
set
{
this.table = value;
}
}
public byte[] GenerateTable(CRC4_POLY polynomial)
{
byte[] csTable = new byte[16];
for (int i = 0; i < 16; ++i)
{
int curr = i;
for (int j = 0; j < 4; ++j)
{
if ((curr & 0x8) != 0)
{
curr = ((curr << 1) & 0x0F) ^ (int)polynomial; // why not?: curr = ((curr ^ (int)polynomial) <<1) & 0x0F;
}
else
{
curr <<= 1;
}
}
csTable[i] = (byte)curr;
}
return csTable;
}
public CRC4Calc(CRC4_POLY polynomial)
{
this.table = this.GenerateTable(polynomial);
}
}
The top bit of the register before shifting out, i.e. the bit being shifted out, determines whether the polynomial is exclusive-or'ed with what remains after shifting. This is precisely the classic shift register implementation.
Related
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.
I am writing a BigBinaryString class in C++ which abstractly holds the large binary string and can perform operations like xor, and, left shift and right shift.
I have stored the binary string internally as a vector of unsigned longs, so each element in vector consumes 64-bits from the bitstring.
I have decided to use have four types of constructors:
BigBinaryString(const string bitstring) //for directly converting the bitstring to internal repr.
BigBinaryString() //initialize the binary string to 0.
BigBinaryString(const size_t num) //hold the binary for corresponding unsigned long.
BigBinaryString(const vector<size_t> vec) //Directly pass the internal repr to the constructor for it to copy.
So far I have implemented and, xor, equality and left shift operators.
However, I feel the left shift operator has a very high time complexity in which the way I have implemented it.
So, I need a few suggestions on how to speed up the left shift operator so that I can implement the right shift efficiently as well.
The code so far is as follows:
#define SIZE_UNSIGNED_LONG (sizeof(size_t) * 8)
class BigBinaryString {
private:
vector<size_t> num;
void reduce() {
while (*num.rbegin() == 0) {
num.pop_back();
}
if (num.size() == 0) {
num.push_back(0);
}
}
public:
BigBinaryString() { num.push_back(0); }
BigBinaryString(const size_t n) { num.push_back(n); }
BigBinaryString(const vector<size_t> vec) {
const size_t length = vec.size();
for (size_t i = 0; i < length; i++) {
num.push_back(vec.at(i));
}
reduce();
}
BigBinaryString operator&(const BigBinaryString& op) {
vector<size_t> vec;
size_t maxlen = max(num.size(), op.num.size());
size_t minlen = min(num.size(), op.num.size());
const size_t zero = 0;
for (size_t i = 0; i < minlen; i++) {
vec.push_back(num.at(i) & op.num.at(i));
}
return BigBinaryString(vec);
}
BigBinaryString(const string bitstring) {
string temp = bitstring;
size_t dec = 0;
while (temp.length() != 0) {
if (temp.length() > SIZE_UNSIGNED_LONG) {
dec = stoul(temp.substr(temp.length() - SIZE_UNSIGNED_LONG,
SIZE_UNSIGNED_LONG),
nullptr, 2);
temp = temp.substr(0, temp.length() - SIZE_UNSIGNED_LONG);
} else {
dec = stoul(temp, nullptr, 2);
temp = "";
}
num.push_back(dec);
}
reduce();
}
BigBinaryString operator^(const BigBinaryString& op) {
vector<size_t> vec;
size_t maxlen = max(num.size(), op.num.size());
size_t minlen = min(num.size(), op.num.size());
for (size_t i = 0; i < maxlen; i++) {
if (i < minlen) {
vec.push_back(num.at(i) ^ op.num.at(i));
} else if (maxlen == num.size()) {
vec.push_back(num.at(i));
} else if (maxlen == op.num.size()) {
vec.push_back(op.num.at(i));
}
}
return BigBinaryString(vec);
}
bool operator==(const BigBinaryString& op) {
if (num.size() != op.num.size()) {
return false;
}
size_t length = num.size();
for (size_t i = 0; i < length; i++) {
if (num.at(i) != op.num.at(i)) {
return false;
}
}
return true;
}
bool operator==(const size_t n) {
BigBinaryString op(n);
if (num.size() != op.num.size()) {
return false;
}
size_t length = num.size();
for (size_t i = 0; i < length; i++) {
if (num.at(i) != op.num.at(i)) {
return false;
}
}
return true;
}
bool operator!=(const BigBinaryString& op) { return not(*this == op); }
bool operator!=(const size_t op) { return not(*this == op); }
BigBinaryString operator<<(size_t shift) {
string bitstring = this->to_string();
bitstring.append(shift, '0');
return BigBinaryString(bitstring);
}
string to_string() {
string suffix = "";
string retval = "";
string prefix = "";
size_t n = 0;
for (auto i = num.rbegin(); i != num.rend(); i++) {
n = *i;
prefix.clear();
suffix.clear();
while (n != 0) {
suffix = (n % 2 == 0 ? "0" : "1") + suffix;
n /= 2;
}
if (i != num.rbegin()) {
prefix.append(SIZE_UNSIGNED_LONG - suffix.size(), '0');
}
prefix = prefix + suffix;
if (prefix.size() == SIZE_UNSIGNED_LONG) {
retval += prefix;
} else if (i == num.rbegin()) {
retval += prefix;
} else if (i != num.rbegin()) {
throw invalid_argument("prefix+suffix error");
}
}
return retval;
}
};
Any help will be appreciated!
So i have got this function.
UINT32 Encrypt(UINT32 instruction, int increment)
{
UINT32 linstruction = _rotl(instruction, 7);
UINT32 rinstruction = _rotr(instruction, 3);
UINT32 key = (0x1F3D8AF * increment) ^ (rinstruction ^ linstruction);
return (key ^ instruction);
}
I need to make a function that actually decrypts this and gets the instruction from the result using a key so it would be like.
t = encrypt(t, i);
t = decrypt(t, key);
Basically i want it to reverse the whole process of the encrypt so it decrypts it and gets me the instruction.
They are used in this function
int RbxOpEncoder::encode(Instruction op, int i, int key) {
int orig = ConvertInstruction(op);
int t = orig;
switch (GET_OPCODE(op)) {
case OP_JMP:
t = ((Encrypt(t, i) & 0x3FFFFFF) | ((orig >> 26 & MASK1(6, 0)) << 0x1A));
break;
case OP_CALL:
case OP_TAILCALL:
case OP_CLOSURE:
case OP_RETURN:
t = ((Calldecrypt(t, i) & 0x3FFFFFF) | ((orig >> 26 & MASK1(6, 0)) << 0x1A));
break;
}
t = EncryptOpcode(t, key);
return t;
}
You may use:
std::uint32_t decrypt(std::uint32_t instruction, int increment)
{
instruction = instruction ^ (0x1F3D8AF * increment);
for (int i = 0; i != 15; ++i) {
instruction = Encrypt(instruction, 0);
}
return instruction;
}
And then you have
decrypt(Encrypt(value, increment), increment) == value
Demo
Basically i cant make work this logic simulator! I made an adjacency list that connects all the gates one to each other and then assign a value to them and AdjList that is the head should calculate the value using the function pointer. Problem is the only function it calls is And!(Xor Nand etc.. are never called)
The specific points are where pointer are initialized
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
and were they are assigned
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
Then in function CalcGateValue() they are called to execute the program! it seems like they are recognised and assigned to the right value in VectorHeadPtr[i].ptrf i tried to cout in that point and it goes into that cycle but the only function called when i call CalcGateValue() is And! Am I missing something?
Here is the complete code:
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int compare(string a, string b)
{
int n = count(a.begin(), a.end(), 'I');
int q = count(b.begin(), b.end(), 'I');
return n > q;
}
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle
{
return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h];
}
bool Xor(vector<bool> inputs)
{ cout<<"Xor function called!"<<endl;
int counter = 0;
for (unsigned int i = 0;i < inputs.size(); i++)
{
if (inputs.at(i) == 1)
{
counter++;
}
}
if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given
{
return 1;
}
else
{
return 0;
}
}
bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe
{ cout<<"And function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if(inputs.at(i) == 0)
{
return 0;
}
}
return 1;
}
bool Nand(vector<bool> inputs)
{ cout<<"Nand function called!"<<endl;
return !And(inputs);
}
bool Or(vector<bool> inputs)
{cout<<"Or function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if (inputs.at(i) != inputs.at(i+1) )
{
return 1;
}
}
return inputs.at(0);//Any position it's ok because all nPoss are the same.
}
bool Nor(vector<bool> inputs)
{ cout<<"Nor function called!"<<endl;
return !Or(inputs);
}
/*
* Adjacency list node
*/
struct AdjListNode
{
int nPos;
bool gValue;
string name;
struct AdjListNode* next;
};
/*
* Adjacency list
*/
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
/**
* Class Graph
*/
class Graph
{
private:
int V;
int circInputs = 3;
int circOutputs = 2;
int circGates;
int PrimaryInputs = 0;
vector<string> ioPuts;
struct AdjList* VectorHeadPtr;
public:
Graph(vector<string> Gate_IO)
{
int ptrPos,cntr;
int cntrIO = 0;
int prevPrimaryInputs = 0;
bool flag_remove_duplicates = 0;
string GateToConnect;
circGates = Gate_IO.size();
V=Gate_IO.size() + circInputs + circOutputs; //nĀ°gates+input+output letti dal file
sort (Gate_IO.begin(), Gate_IO.end(), compare);
for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++)
{
PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I');
prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I');
}
PrimaryInputs = cntr; //Here starts first N
for (int i = 0;i<Gate_IO.size();i++)
VectorHeadPtr = new AdjList [V];
for (int i = 0; i < V; i++)
{
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
VectorHeadPtr[i].head = NULL;
stringstream ss;
ss << Gate_IO[i];
for (string temp; ss >> temp;)
{
if ( (temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR") )
{
ioPuts.push_back(temp);
}
else if (temp.at(0) == 'U')
{
VectorHeadPtr[i].GateName=temp;
}
}
ptrPos = Gate_IO[i].find_last_of(' ');
VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos);
}
else
{
if (flag_remove_duplicates == 0)
{
sort (ioPuts.begin(), ioPuts.end() );
ioPuts.erase (unique (ioPuts.begin(), ioPuts.end() ), ioPuts.end() );
flag_remove_duplicates = 1;
}
VectorHeadPtr[i].head = NULL;
VectorHeadPtr[i].ptrf = NULL;
VectorHeadPtr[i].GateName = ioPuts[cntrIO];
cntrIO++;
}
}
for (int i = 0; i < Gate_IO.size(); i++)
{
for(int j = 0; j < 2; j++)
{
ptrPos = Gate_IO[i].find_first_of(' ')+1;
Gate_IO[i].erase (0,ptrPos);
}
ptrPos = Gate_IO[i].find_last_of(' ')+1;
Gate_IO[i].erase( ptrPos);
stringstream ss;
ss << Gate_IO[i];
ss >> GateToConnect;
for (string temp; ss >> temp;)
{
addEdge(GateToConnect,temp);
}
}
}
/**
* Creates new adjacency list node for addEdge function
*/
AdjListNode* newAdjListNode(int nPos, string Name)
{
AdjListNode* newNode = new AdjListNode;
newNode->nPos = nPos;
newNode->name = Name;
newNode->next = NULL;
return newNode;
}
/**
* Add edge to graph
*/
void addEdge(string source, string destination)
{
int from, to;
for (int i = 0; i < V; ++i)
{
if ( (source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName) )
{
from = i;
}
else if (( destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName) )
{
to = i;
}
}
AdjListNode* newNode = newAdjListNode(to, destination);
newNode->next = VectorHeadPtr[from].head;
VectorHeadPtr[from].head = newNode;
}
/*
* Print the graph
*/
void printGraph()
{
for (int i = 0; i < circGates; i++)//meno ooutput+input
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName;
while (Ptr)
{
cout <<"-> "<< Ptr->name;
Ptr = Ptr->next;
}
cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl;
}
}
void calcGateVal()
{
vector<bool> Val={0, 1, 0};
vector<bool> Op;
for (int i = 0; i < circOutputs; i++)
{
ioPuts.pop_back();
}
for (int i = 0; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
if (Ptr->name.at(0) == 'I')
{
for (int j = 0; j < ioPuts.size(); j++)
{
if (Ptr->name == ioPuts[j])
{
Ptr->gValue = Val[j];
}
}
}
Ptr = Ptr->next;
}
}
for (int i = 0; i < PrimaryInputs; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op);
cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl;
Op.clear();
}
for (int i = PrimaryInputs; i < V; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
for (int j = 0; j < PrimaryInputs; j++)
{
if (Ptr->name == VectorHeadPtr[j].OutputName)
{
Ptr->gValue = VectorHeadPtr[j].result;
}
}
Ptr = Ptr->next;
}
}
for (int i = PrimaryInputs; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op);
Op.clear();
}
}
void displayOutput()
{ cout<<endl;
for (int i = 0; i < circGates; i++)
{
cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl;
}
}
};
/*
* Main
*/
int main()
{
vector<string> G_d;
G_d.push_back("AND 2 U0 I0 I1 N0");
G_d.push_back("XOR 2 U1 N0 I2 O0");
G_d.push_back("AND 2 U2 N0 I2 N1");
G_d.push_back("AND 2 U3 I0 I1 N2");
G_d.push_back("OR 2 U4 N1 N2 O1");
Graph gh(G_d);
gh.calcGateVal();
gh.displayOutput();
gh.printGraph();
// print the adjacency list representation of the above graph
return 0;
}
I think your code does not produce what you say it produces. Please see here:
http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this
Why do you want to convert strings to integers with strtoi with your case comparisons? :
case strtoi("NAND"):
a better approach would be strcmp or store each in a string perhaps a look up table and do a "==" equal equal comparison which is overloaded for strings.
Consider passing your vectors and objects around by reference rather than value, you might be expecting a return in your object but since you pass by value you never see them and this also avoids the overhead of making a copy of the vectors.
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. ;)