我不太擅长C,所以我有一些问题。
我有以下两种结构:
typedef struct line_elems line;
typedef struct cache_handler *cache;
struct line_elems { // we don't care about valid/block bits in our simulator
int tag;
int freq; // for LRU principle
};
struct cache_handler {
int hit;
int miss;
int evict;
line **lines; // 2d array for sets
};
通过以下方式初始化缓存:
cache make_cache(int s, int E) {
int i;
cache new = malloc(sizeof(struct cache_handler));
new->hit = 0;
new->miss = 0;
new->evict = 0;
line **new_line = malloc((1 << s) * sizeof(*new_line));
for(i = 0; i < (1 << s); i++)
new_line[i] = malloc(E * sizeof(struct line_elems));
new->lines = new_line;
return new;
}
现在,我想创建一个系统来搜索二维数组中的一行:
int search_lines(line *lines, int E, int tag, int frequency) {
int i;
for(i = 0; i < E; i++) {
//continue here
}
}
我对我应该在search_lines函数中输入的内容感到有些困惑。
如果我输入:search_lines(cache->lines[0], E=5, tag=5, frequency=5)
它会做我期待的吗?也就是说,它会在我的2d数组中搜索一行吗?我觉得cache->lines[0]
与(line*)
不一样。
cache->lines
和cache->lines[0]
之间有什么区别?这让我感到困惑,因为->
运算符是否隐式执行了一级解除引用?
谢谢。
答案 0 :(得分:2)
->
运算符未取消引用lines
,它取消引用cache
。这是必要的,因为cache
也是一个指针(通过调用malloc
创建。)因此,在访问其任何字段之前必须取消引用它。
cache->lines
是line **
cache->lines[0]
是line *
答案 1 :(得分:2)
"What is the difference between a cache->lines and a cache->lines[0]?"
cache->lines
是struct line_elems**
,这是您的2D数组。实际上它是指向2D数组的第一个元素的指针。使用了运算符->
,因为cache
是cache_handler*
=您正在使用它来访问struct cache_handler
的成员。
cache->lines[0]
是struct line_elems*
,它是索引0处的一维数组=它也是指向二维数组第一个元素的指针。
请注意,释放此内存的顺序应与分配顺序相反:
line **new_line = malloc((1 << s) * sizeof(*new_line));
for(i = 0; i < (1 << s); i++)
new_line[i] = malloc(E * sizeof(struct line_elems));
首先释放每个new_line[i]
,然后释放new_line
本身:
for(i = 0; i < (1 << s); i++)
free(new_line[i]);
free(new_line);
答案 2 :(得分:1)
是的,cache-&gt; lines [0]的引用确实会返回一个指向你所分配的'lines'数组的指针,因此你的示例调用实际上是正确的方法。
请记住,cache-&gt;行是一个已分配的指针数组(第二次调用malloc
)。它只为2^s * the_size_of_a_pointer
下面的其余malloc为E * size_of_a_line
分配足够的空间。
因此,当您取消引用缓存指针(使用->
)然后使用行指针(通过使用[0]
)时,最终会得到一个指向E
行的内存指针。< / p>
然后在你的函数中,你可以使用lines[0]
到第一行,lines[E-1]
到达传入的任何行指针数组的最后一行(基于{{1 }}运算符到[]
数据指针)。