2012-04-10 14 views
-3

Als Übung (hauptsächlich eine Übung in dem Versuch, etwas mit Zeigern zu schreiben), schreibe ich eine Cache-Simulation, speziell des Pseudo-unlängst verwendeten Systems aus dem alten 486. Ich bin eine „Zugriffsverletzung Leseort“ Fehler auf der Linie bekommen:C++ Zeiger "verliert" seinen Wert

int min = treeArray[set]->root->findPLRU(); 

zunächst die treeArray scheint richtig initialisiert zu werden (wenn ich das Programm beim Start unterbrechen und einen Blick darauf werfen, es ist alles so sein soll), aber Wenn das Programm abbricht und ich mich eingehender mit den Dingen beschäftige, ist die Wurzel des fraglichen Baums nicht definiert. Ich denke, es ist ziemlich wahrscheinlich, dass ich einen sehr elementaren Zeigerfehler mache, der dazu führt, dass der Zeiger auf den Knoten irgendwo "verloren geht", aber ich habe keine Ahnung, was es sein könnte. Muss ich etwas Besonderes tun, um einen Zeigerwert zu "halten"?

Vielen Dank im Voraus für jede Hilfe, die Sie geben können!

#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; 
} 
+3

lässt sich nicht kompilieren: http://ideone.com/qCewp – elmo

+0

Entschuldigung. Ich hatte nur die spezifische Funktion, in der das Problem lag, eingefügt - aber das reicht natürlich nicht, um weiterzumachen. Es tut uns leid! (voller Code da jetzt) ​​ –

Antwort

5

ich diese beantworten bin, weil ich für (= & Befund =) Antworten auf meine Fragen kommen hier meist nur auf der Suche & viel zurück, nicht zu stören neigen zu geben.

Und Ihre Frage ist die einzige, auf die noch nicht gestoßen wurde; wahrscheinlich, weil Ihr Code * immer noch nicht kompiliert, da Sie nicht main.h

Und selbst dann würde es ärgern die meisten Leute versuchen, Ihnen zu helfen, weil Sie keine Erwähnung der ico0.trace Datei, die erforderlich ist, um die zu verhindern Code vom sofortigen Beenden. lol


Sie sagen int min = treeArray[set]->root->findPLRU(); Zugriff verletzt.

1) der Wert von set kann niemals die Größe n Ihr überschreitet treeArray da Sie den Bereich der Eingabewerte & n-1.

2), da Ihr ~Tree() destructor ist nie dort genannt wird immer ein treeArray[set]->root

3 sein), da Sie * immer neu erstellen left & right Knoten, wenn leftCacheLine = -1 oder rightCacheLine = -1 es nicht durch sein findPLRU s rekursiven


So. Der Zeiger auf den Knoten ist nicht irgendwo "verloren"; es wird aufgestampft.

versuchen zu ersetzen:

int min = treeArray[set]->root->findPLRU(); 
    c[min].tag = tag; 
    c[min].access = access; 

mit:

int min = treeArray[set]->root->findPLRU(); 
    if (min >= k*n) 
    { 
     printf("ook\n"); 
    } 
    else 
    { 
     c[min].tag = tag; 
     c[min].access = access; 
    } 

und ich denke, Sie werden entdecken, was das Stampfen tut;)

+0

Entschuldigung, und nochmals entschuldigt. Du hast absolut recht, ich habe diese Frage so formuliert, dass sie im Grunde nicht zu beantworten ist.Und trotzdem ist es dir irgendwie gelungen, einer Antwort nahe genug zu kommen, um mich aus den scheinbar geistlosen Stunden herauszuholen, die ich damit verbracht habe, es herauszufinden. Vielen Dank! –

+0

noP ~ & viel Glück mit diesen Knoten;) – violet313

+0

+1 für die Mühe, um dies zu lösen, trotz der nicht kompilierenden Beispiel. – Fraser