2012-04-10 15 views
-3

練習問題(主にポインターを使って何かを書き込もうとする試み)として、私はキャッシュシミュレーションを書いています。ライン上の「アクセス違反読み取り場所」エラーを取得: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ファイルコードはすぐに終了します。あなたがint min = treeArray[set]->root->findPLRU();と言う場合、アクセス違反です。

1)setの値は、あなたので、入力値の& n-1範囲をサイズあなたtreeArraynを超えることはできません。あなたの~Tree()デストラクタがあなたは、常に新しいleft & rightノードを作成します*ので、それが原因再帰findPLRU

にすることはできませんいつでもleftCacheLine = -1またはrightCacheLine = -1常に)treeArray[set]->root

3が存在することになると呼ばれることはありませんされているので

2)


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

関連する問題