Reputation: 3315
I'm not very good at C yet so I have some questions.
I have two of the following structs:
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
};
In initialized the cache by:
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;
}
Now, I want to create a system to search through a single row in the 2d array:
int search_lines(line *lines, int E, int tag, int frequency) {
int i;
for(i = 0; i < E; i++) {
//continue here
}
}
I'm a little confused on what exactly I'm supposed to input into my search_lines function.
If I input: search_lines(cache->lines[0], E=5, tag=5, frequency=5)
Will it do what I'm expecting? That is, will it search through a single line in my 2d array? I feel that cache->lines[0]
is not the same as a (line*)
.
What is the difference between a cache->lines
and a cache->lines[0]
? This is confusing me because does the ->
operator implicitly perform one level of dereferencing?
Thank you.
Upvotes: 2
Views: 1321
Reputation: 42083
"What is the difference between a cache->lines and a cache->lines[0]?"
cache->lines
is struct line_elems**
which is your 2D array. Actually it is a pointer to first element of your 2D array. Operator ->
is used because cache
is cache_handler*
= you are accessing members of struct cache_handler
with it.
cache->lines[0]
is struct line_elems*
which is 1D array at index 0 = it is also a pointer to first element of your 2D array.
Note that freeing of this memory should have opposite order than your allocation:
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));
you free each new_line[i]
first and after that you free new_line
itself:
for(i = 0; i < (1 << s); i++)
free(new_line[i]);
free(new_line);
Upvotes: 2
Reputation: 22252
Yes, the reference of cache->lines[0] does indeed return a pointer to your allocated array of 'lines', and thus yes your example call is in fact the right way to do it.
Remember that the cache->lines is a allocated array of pointers (the second call to malloc
). It merely allocates enough space for 2^s * the_size_of_a_pointer
The rest of the mallocs below that allocate enough space for E * size_of_a_line
.
So when you dereference the cache pointer (using ->
) and then deference the lines pointer (by using [0]
) then you end up with a memory pointer to E
lines.
Then in your function, you can use lines[0]
to get to the first line, and lines[E-1]
to get to the last of whatever array of line pointers was passed in (based on the []
operator to the cache->lines
data pointer).
Upvotes: 1
Reputation: 19304
The ->
operator is not dereferencing lines
, it is dereferencing cache
. This is necessary because cache
is also a pointer (created by a call to malloc
.) Thus, it must be dereferenced before accessing any of its fields.
cache->lines
is a line **
cache->lines[0]
is a line *
Upvotes: 2