简体   繁体   中英

C Array of Linked List Struct on Heap

typedef struct cache_line {
    char valid;
    mem_addr_t tag;
    struct cache_line* next;
} cache_line_t;

typedef cache_line_t* cache_set_t;
typedef cache_set_t* cache_t;


/* The cache we are simulating */
cache_t cache;


void initCache()
{
        cache = malloc (S * sizeof(cache_set_t));
        for (int i = 0; i < S; i ++ ){
                cache[i]= malloc(sizeof(cache_line_t));
                cache_line_t *temp = *(cache+i);

                temp -> valid = 0;
                temp -> tag = 0;
                cache_line_t* curr = *(cache+ i );
                for (int j = 1; j < E; j++){
                        curr.next = malloc(sizeof(cache_line_t));
                        curr = curr.next;
                        curr.valid=0;
                        curr.tag=0;
                }
                curr.next = NULL;
        }

}

So my head is swimming trying to remember all the details of pointers and structs and I've been up for a while trying to finish this project. What I'm trying to do here is allocate an array of this structure (a linked list) on the heap and I keep having issues with type mismatches and whatnot (sorry if its messy I keep on trying new things and recompiling). Any help on where I'm going wrong would be appreciated.

Well, the fact the code is terribly obfuscated with abuse of typedef probably goes a long way towards both yours and the compilers problems. I wouldn't have a single typedef in this program myself. It serves no real abstraction here. Here's what I'd suggest (with some omission of error checking):

struct cache_line {
    char valid;
    mem_addr_t tag;
    struct cache_line* next;
};

struct cache_line** cache;

void initCache()
{
    cache = malloc (sizeof(*cache) * S);
    for (int i = 0; i < S; i ++ ){
        struct cache_line** curr_p = &cache[i];
        for (int j = 1; j < E; j++){
            *curr_p = malloc(sizeof(**curr_p));
            (*curr_p)->valid = 0;
            (*curr_p)->tag = 0;
            (*curr_p)->next = NULL;
            curr_p = &(*curr_p)->next;
        }
    }
}

Key things to note:

  1. I removed all the typedefs. They served no real purpose here but an attempt to save typing. And they did it at the cost of code quality. I also removed it from the struct , since I believe the previous statement applies to it as well.

  2. I allocated memory canonically. By writing malloc(sizeof(*pointer_variable)) , you allocate enough memory regardless of what pointer_variable points at. It's somewhat type agnostic.

  3. I traverse the linked list with the "link traversal" idiom. Instead of keeping track of the "node", I keep track of the pointer that is pointing at the node. In the beginning it's cache[i] , and at every iteration it becomes the pointer inside the newly allocated node.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM