2012-04-10 5 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

+0

사과. 문제가 발생한 부분에만 특정 기능을 포함 시켰습니다. 물론 그렇게할만한 것은 아닙니다. 죄송합니다! (지금 전체 코드) –

답변

5

난 대부분 단지 훨씬 다시 답례로주는 귀찮게하지 않는 경향이 & 질문에 (= & 발견 =) 답을 찾고 여기 온 때문이다.

그리고 아직 질문에 불만을 표시하지 않은 질문 만 있습니다. 아마도 여러분의 코드가 main.h를 제공하지 않았기 때문에 여전히 컴파일되지 않았기 때문일 것입니다.

그리고 심지어 여러분을 도우려는 대부분의 사람들을 괴롭 히곤합니다. 왜냐하면 여러분이 코드를 막는 데 필요한 ico0.trace 파일을 언급하지 않았기 때문입니다. 코드가 즉시 종료됩니다. lol


당신은 int min = treeArray[set]->root->findPLRU();에 대한 접근을 침해한다고 말합니다.

1) 입력 값의 범위가 & n-1이므로 set의 값은 의 크기를 절대 초과 할 수 없습니다. 당신의 ~Tree() 소멸자 이후

2) 항상있을 것입니다 호출되지 않은 treeArray[set]->root

3) * 항상 findPLRU

재귀하는 것이 원인 일 수 없을 때마다 leftCacheLine = -1 또는 rightCacheLine = -1 새로운 left & right 노드를 만들 수 있기 때문에


So. 노드에 대한 포인터는 이 아니며은 어딘가에 없습니다. 그것은 밟히고있다.

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

다시 사과하고 사과드립니다. 당신은 절대적으로 옳습니다. 저는 기본적으로 대답 할 수없는 방식으로이 질문을 구성했습니다.그럼에도 불구하고 당신은 여전히 ​​여하튼 그 대답을 이해할 수있을만큼 충분히 가까이 다가 가려고 노력했습니다. 감사! –

+0

noP ~ 그 노드들에게 행운을 빕니다.) – violet313

+0

+1 컴파일하지 않은 샘플에도 불구하고이를 해결하기위한 노력. – Fraser