gpt4 book ai didi

c++ - 为什么类中的 vector 自动变为 NULL

转载 作者:行者123 更新时间:2023-11-28 01:20:30 24 4
gpt4 key购买 nike

我正在创建简单的缓存模型来模拟某些应用程序。

但是,下面代码中的 lru 出现了问题。 (我没有复制不相关的代码)

main.cpp

int main(void) {
Cache* L1Cache = new Cache(64, 64, 8);
Cache* L2Cache = new Cache(256, 64, 4);
Cache* L3Cache = new Cache(2048, 64, 16); // This object causes problem
Cache* L4Cache = new Cache(2048, 64, 8);

L1Cache->initCache();
L2Cache->initCache();
L3Cache->initCache();
L4Cache->initCache();
return 0;
}

缓存.h

typedef struct CacheLine {
std::vector<uint64_t> data;
}CacheLine;

typedef struct CacheSet {
std::vector<bool> valid;
std::vector<uint64_t> tag;
std::vector<CacheLine> directory;
}CacheSet;

typedef struct LRU {
std::vector<std::vector<bool>> lruMatrix;
}LRU;


class Cache {
public:
Cache(uint32_t cacheSizeInKB, uint32_t lineSizeInByte, uint32_t numOfDirs) {
// set cache size
this->cacheSizeInKB = cacheSizeInKB;
this->lineSizeInByte = lineSizeInByte;
this->numOfDirs = numOfDirs;
this->numOfSets = (cacheSizeInKB * 1024) / (lineSizeInByte * numOfDirs);

// set memory address offset
this->blockOffsetFrom = log2(lineSizeInByte) - 1;
this->blockOffsetTo = 0;
this->indexOffsetFrom = this->blockOffsetFrom + ceil(log2(this->numOfSets));
this->indexOffsetTo = this->blockOffsetFrom + 1;
this->tagOffsetFrom = 63;
this->tagOffsetTo = this->indexOffsetFrom + 1;

// reserve vectors before using
cache.reserve(this->numOfSets);
for (int x = 0; x < this->numOfSets; ++x) {
cache[x].valid.reserve(numOfDirs);
cache[x].tag.reserve(numOfDirs);
cache[x].directory.reserve(numOfDirs);
for (int y = 0; y < this->numOfDirs; ++ y) {
cache[x].directory[y].data.reserve(lineSizeInByte / 8);
}
}

lru.reserve(this->numOfSets);
for (int i = 0; i < this->numOfSets; ++i) {
lru[i].lruMatrix.reserve(numOfDirs);
for (int j = 0; j < this->numOfDirs; ++j) {
lru[i].lruMatrix[j].reserve(numOfDirs);
}
}

std::cout << "1: " << &lru[0].lruMatrix[0] << std::endl; // this shows correct memory address space
}

void initCache();
void accessData(uint64_t addr);
void printLRUMatrix(uint64_t index);

private:
const uint32_t HIT = 1;
const uint32_t MISS = 0;
// cache size list
uint32_t cacheSizeInKB;
uint32_t lineSizeInByte;
uint32_t numOfDirs;
uint32_t numOfSets;

// offset list
uint64_t blockOffsetFrom;
uint64_t blockOffsetTo;
uint64_t indexOffsetFrom;
uint64_t indexOffsetTo;
uint64_t tagOffsetFrom;
uint64_t tagOffsetTo;

std::vector<CacheSet> cache;
std::vector<LRU> lru;
};

缓存.cpp

void Cache::initCache() {
for (int x = 0; x < numOfSets; ++x) {
for (int i = 0; i < numOfDirs; ++i) {
cache[x].valid[i] = false;
cache[x].tag[i] = 0;
for (int j = 0; j < numOfDirs; ++j)
cache[x].directory[i].data[j] = 0;
}
}

std::cout <<"2: " << &lru[0].lruMatrix[0] << std::endl; // This prints out 0 address in case of L3Cache
/*
for (int i = 0; i < numOfSets; ++i) {
std::cout << "i: " << i << std::endl;
for (int j = 0; j < numOfDirs; ++j) {
std::cout << "j: " << j << std::endl;
for (int k = 0; k < numOfDirs; ++k) {
std::cout << "k: " << k << std::endl;
this->lru[i].lruMatrix[j][k] = false;

}
}
}
*/
}

输出

1: 0x9464d0
1: 0x9f5190
1: 0xded230
1: 0x140d2d0
2: 0x9464d0
2: 0x9f5190
2: 0
2: 0x140d2d0

我在上面的代码中遇到了奇怪的情况。

在 L3Cache 的情况下,lru[0].lruMatrix[0] 的地址在 Cache constructor(0xded230) 和成员函数 initCache()(0 ).

但是,其他情况,如 L1Cache、L2Cache、L4Cache 在 constructorinitCache() 之间打印正确(相同)的地址。

唯一的区别是 L3Cache 使用的 numOfDir 16 比其他的大。

我不明白为什么会这样。看来我的代码没有错误。

有什么问题吗?

最佳答案

您正在越界读取 lru

假设在 Cache::initCache() 运行之前没有其他东西触及 Cache::lru,这个 std::vector 将在默认为空状态。由于该函数中没有任何内容会增加 lru 的大小,因此当您点击此行时它仍然是空的:

std::cout <<"2: " << &lru[0].lruMatrix[0] << std::endl;

在其中,您有 lru[0]。这是取消引用 lru 的第一个元素,它不存在。这是未定义的行为任何都可能发生。不要这样做。在取消引用之前,您需要确保位置 0 存在某些内容。

lru[0].lruMatrix 处的 vector 地址显示为零的原因可能是因为 vector 最初将其动态分配的指针设置为数组成为空指针。因此,取消引用第一个元素就是取消引用空指针。这是您的特定标准库供应商的实现细节;不要依赖这种行为。


我还在您的代码中看到以下模式:

lru.reserve(this->numOfSets);
for (int i = 0; i < this->numOfSets; ++i) {
lru[i].doSomething();
...

出于同样的原因,这是未定义的行为。 std::vector::reserve 不会改变 vector 的大小。它只分配存储空间。你可能想要 std::vector::resize

关于c++ - 为什么类中的 vector 自动变为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56509722/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com