2012-04-10 99 views
-3

作爲一個練習(很大程度上是嘗試使用指針編寫某些東西的練習),我正在編寫一個高速緩存仿真,特別是舊的486最近使用的僞最近系統。收到「訪問衝突讀取位置」上線錯誤:C++指針「丟失」它的值

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

最初treeArray似乎是正確初始化(如果我在一開始暫停節目,並採取一看,這一切都爲應該是),但當程序中斷並且我深入研究事物時,沒有定義所討論的樹的根。我覺得我很可能會犯一些非常基本的指針錯誤,這會導致指向節點的指針在某處「丟失」,但我不知道它會是什麼。我需要做些什麼來「堅持」指針值?

在此先感謝您的幫助!

#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

不會編譯:http://ideone.com/qCewp – elmo 2012-04-10 14:59:56

+0

道歉。我只是將問題的具體功能包括在內 - 但當然,這還不足以繼續。抱歉! (現在有完整的代碼) – 2012-04-10 16:37:40

回答

5

我回答這個問題,因爲我大多隻是來這裏尋找(= &發現=)答案&往往不會打擾給多少回的回報問題。

而你的問題是唯一一個還沒有被撲滅的問題;可能是因爲你的代碼*仍然不能編譯,因爲你還沒有提供main.h

即使這樣,它會惹惱大多數人試圖幫助你,因爲你沒有提到防止這個問題所需的ico0.trace文件代碼立即退出。大聲笑


你說int min = treeArray[set]->root->findPLRU();訪問違反。

1)set的值永遠不會超過treeArrayn的大小,因爲您的輸入值範圍爲& n-1

2),因爲你的~Tree()析構函數是從未稱爲總是會有一個treeArray[set]->root

3)因爲你*總是創建每當leftCacheLine = -1rightCacheLine = -1它不能因新left & right節點遞歸findPLRU小號


所以。指向節點的指針是而不是在某處「丟失」;它正在被踩踏。

嘗試更換:

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

有:

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

,我想你會發現什麼做跺腳;)

+0

道歉,並再次道歉。你是對的,我已經以這樣一種基本無法回答的方式來構思這個問題。然而,你仍然設法得到足夠接近的答案,以幫助我擺脫我花費在嘗試弄清楚的明顯無意識的時間。謝謝! – 2012-04-11 07:45:52

+0

noP〜&祝你好運與這些節點;) – violet313 2012-04-11 17:09:16

+0

+1努力解決這個問題,儘管非編譯樣本。 – Fraser 2012-04-11 22:06:50