-2

演習(主にポインタを使用して何かを書き込もうとする演習)として、特に古い486の疑似最も最近使用されていないシステムのキャッシュシミュレーションを作成しています。「アクセス違反の読み取り場所」エラーが発生します。この線:

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

最初はtreeArrayが適切に初期化されているように見えますが(最初にプログラムを一時停止して見てみると、すべて正常です)、プログラムが壊れて、問題のツリーのルートがないことを調べてみると、 tが定義されています。

ある種の非常に基本的なポインタの間違いを犯している可能性が非常に高いと思います。これにより、ノードへのポインタがどこかで「失われ」ますが、それが何であるかはわかりません。ポインタ値を「保持」するために特に行う必要があることはありますか?

#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;
}
4

1 に答える 1

6

おそらく、提供していないためにコードがまだコンパイルされていないため、あなたの質問はまだ急襲されていませんmain.h

ico0.traceそれでも、コードがすぐに終了するのを防ぐために必要なファイルについて言及していないため、あなたを助けようとしているほとんどの人を悩ませるでしょう.

int min = treeArray[set]->root->findPLRU();アクセスが違反しているとあなたは言います。

1)入力値の範囲である ため、 の値が のサイズをset超えることはありません。ntreeArray& n-1

2)~Tree()デストラクタが呼び出されることはないため、常にtreeArray[set]->root

3) *常に新しいleft&rightノードを作成するleftCacheLine = -1か、再帰的なsrightCacheLine = -1が原因ではないため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;
    }

何が足を踏み鳴らしているのかがわかると思います。;)

于 2012-04-10T21:23:38.313 に答える