在C中使用2d数组的结构

时间:2012-02-27 16:59:44

标签: c pointers struct

我不太擅长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->linescache->lines[0]之间有什么区别?这让我感到困惑,因为->运算符是否隐式执行了一级解除引用?

谢谢。

3 个答案:

答案 0 :(得分:2)

->运算符未取消引用lines,它取消引用cache。这是必要的,因为cache也是一个指针(通过调用malloc创建。)因此,在访问其任何字段之前必须取消引用它。

cache->linesline **

cache->lines[0]line *

答案 1 :(得分:2)

"What is the difference between a cache->lines and a cache->lines[0]?"

cache->linesstruct line_elems**,这是您的2D数组。实际上它是指向2D数组的第一个元素的指针。使用了运算符->,因为cachecache_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 }}运算符到[]数据指针)。