Search code examples
cpointersmemorydynamic-memory-allocation

Accessing data in array segmentation fault


I'm encountering a segmentation fault in my program and I'm pretty sure it's a silly mistake! When I try to access data in my arrays of structs I get a segemtentation fault.

struct block {
  int validBit;                        
  int tag;                            
  unsigned long data;              
};
typedef struct block block_t;

struct set{
 block_t *blocks;
 int tst;
};
typedef struct set set_t;

struct cache{
  //bunch of variables I have left out for this question

  set_t *set;
};
typedef struct cache cache_t;

So the allocation of memory to these are

cache_t *cache = NULL;
cache = malloc(sizeof(*cache);
if(cache == NULL){
  fprintf(stdout,"Could not allocate memory for cache!");
}

cache->set = malloc(16 * sizeof(*cache->set));
if(cache->set == NULL){
  fprintf(stdout,"Could not allocate memory for cache->set!");
 }

cache->set->blocks = malloc(2 * sizeof(*cache->set->blocks));
if(cache->set->blocks == NULL){
 fprintf(stdout,"Could not allocate memory for cache->set->blocks!");
}

The cache holds an array of sets with 16 elements. The cache->sets holds an array of blocks with 2 elements.

When I try to set the value of variables inside a block struct a segmentation error arises.

cache->set[0].blocks[0].tag = 1; //This works
cache->set[0].blocks[1].tag = 2; //This works
cache->set[1].blocks[0].tag = 3; //Segmentation fault

EDIT: It seems there is a problem with the variable "tag" inside blocks. If i assign a value to validbit in set[1] it does not produce a segmentation fault.

cache->set[1].blocks[0].validBit = 3; // This works
cache->set[1].blocks[0].tag = 3; //does not work

So it seems to be an issue with the tag variable? Makes no sense to me

Thanks in advance :)


Solution

  • You are not allocating memory for your "block_t" beyond set[0].

    Roughly, you should be doing something along these lines:

    cache = malloc(sizeof *cache);
    cache->set = malloc(num_sets * sizeof *cache->set);
    for (i = 0; i < num_sets; i++) {
        cache->set[i].blocks = malloc(...);
    }