我正在写一个缓存模拟器。我运行gdb来找出我的seg-fault在哪里,它在以下for循环中:
for (int i = 0; i < cache->numSets; ++i)
{
for (int j = 0; j < cache->nLinesPerSet; ++j)
{
cache->sets[i].lines[j].valid = 0;
}
}
这是完整的代码,有助于提供上下文信息,并避免对问题可能出在哪里的任何假设。
谁能告诉我我的错误在哪里?
谢谢!
#include "cache-sim.h"
#include <stdbool.h>
#include <stddef.h>
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
/** Create and return a new cache-simulation structure for a
* cache for main memory withe the specified cache parameters params.
* No guarantee that *params is valid after this call.
*/
/* GET SET ID
//calculate address tag and set index
mem_addr_t addr_tag = addr >> (par.s + par.b);
int tag_size = (64 - (par.s + par.b));
unsigned long long temp = addr << (tag_size);
unsigned long long setid = temp >> (tag_size + par.b); */
typedef struct CacheLineImpl{
MemAddr addr;
unsigned tag;
int valid;
int LRUVal;
}CacheLine;
typedef struct CacheSetImpl{
CacheLine *lines;
int numLines;
unsigned mruHolder;
}CacheSet;
struct CacheSimImpl{
CacheSet *sets;
int numSets;
//CacheParams params;
unsigned nSetBits; /** s # of seets is 2** this */
unsigned nLinesPerSet; /** E # of cache lines/ set */
unsigned nLineBits; /** b # of bytes/line is 2**this */
unsigned nMemAddrBits; /** m # of primary mem addr;
total primary addr space is 2**this*/
Replacement replacement; /** replacement strategy*/
};
CacheSim *
new_cache_sim(const CacheParams *params)
{
CacheSim *cache;
cache = malloc(sizeof(*cache));
cache->nSetBits = params->nSetBits;
cache->nLinesPerSet = params->nLinesPerSet;
cache->nLineBits = params->nLineBits;
cache->nMemAddrBits = params->nMemAddrBits;
cache->replacement = params->replacement;
//unsigned s = cache-> params.nSetBits;
//unsigned E = cache-> params.nLinesPerSet;
cache->numSets = (1 << cache->nSetBits));
//malloc size of CachSimImpl struct
cache->sets = malloc((cache->numSets)* (sizeof(*cache->sets)));
cache->sets->lines = malloc(cache->nLinesPerSet* (sizeof(*cache->sets->lines)));
for (int i = 0; i < cache->numSets; ++i)
{
for (int j = 0; j < cache->nLinesPerSet; ++j)
{
cache->sets[i].lines[j].valid = 0;
}
}
return cache;
}
/** Free all resources used by cache-simulation structure *cache */
void
free_cache_sim(CacheSim *cache)
{
//free all memory used
free(cache->sets->lines);
free(cache->sets);
free(cache);
}
/** Return non-zero iff addr hits cache */
CacheResult
cache_sim_result(CacheSim *cache, MemAddr addr)
{
CacheResult result = { CACHE_MISS_WITH_REPLACE, 0x1234 };
unsigned s = cache->nSetBits;
unsigned E = cache->nLinesPerSet;
unsigned b = cache->nLineBits;
unsigned m = cache->nMemAddrBits;
Replacement replace = cache->replacement;
//cache->sets->lines->valid = 0;
unsigned tagBits = m-(s+b);
//printf("tagBits: %u", tagBits);
unsigned tag = addr << (s + b);
//printf("tag: %u", tag);
unsigned temp = addr << (tagBits);
//printf("temp: %u", temp);
int setIndex = temp >> (tagBits +b);
//printf("setIndex: %d", setIndex);
time_t timer;
srand((unsigned) time(&timer));
bool validLine = true;
for (int i = 0; i < E; ++i)
{
if(cache->sets[setIndex].lines[i].tag != tag){
//track if a valid line exists in the set
if(cache->sets[setIndex].lines[i].valid !=0){
validLine = false;
}
else{
validLine = true;
cache->sets[setIndex].lines[i].valid = 1;
}
}
else{
result.status = CACHE_HIT;
cache->sets->mruHolder = tag;
break;
}
}
if(validLine == true){
for (int i = 0; i < E; ++i)
{
if(cache->sets[setIndex].lines[i].valid == 0){
cache->sets[setIndex].lines[i].tag = tag;
result.status = CACHE_MISS_WITHOUT_REPLACE;
cache->sets->mruHolder = tag;
break;
}
}
}
else{
if (replace==LRU_R){ //replacement strategy is LRU
int i = E - 1;
cache->sets[setIndex].lines[i].tag = tag;
result.status = CACHE_MISS_WITH_REPLACE;
result.replaceAddr = addr;
//break;
}
else if(replace==MRU_R){ //replacement strategy is MRU
for (int i = 0; i < E; ++i)
{
if(cache->sets[setIndex].lines[i].tag ==
cache->sets->mruHolder){
cache->sets[setIndex].lines[i].tag=tag;
result.status = CACHE_MISS_WITH_REPLACE;
result.replaceAddr = addr;
cache->sets->mruHolder = tag;
//break;
}
}
}
else{ //replacement strategy is Random
int i = 0;
i = rand () % E;
cache->sets[setIndex].lines[i].tag = tag;
result.status = CACHE_MISS_WITH_REPLACE;
result.replaceAddr = addr;
//break;
}
}
return result;
}
最佳答案
问题是您为内部数组分配了错误的内存。
cache->sets = malloc((cache->numSets)* (sizeof(*cache->sets)));
cache->sets->lines = malloc(cache->nLinesPerSet* (sizeof(*cache->sets->lines)));
cache->sets->lines = ...
等效于cache->sets[0].lines = ...
,因此对于i
大于0的情况,您将访问无效的内存。正确的方法可能是:
for (i = 0; i < cache->numSets; ++i) {
cache->sets[i].lines = malloc(...);
}