1

I have a pointer to a pointer to a structure and I am trying to access a pointer-to-pointer pointer within that structure. I keep getting an error that reads: "request for member 'buckets' in something not a structure or union." I commented next to the error. So my question is, how do I properly access buckets and allocate memory for it.

typedef struct bucket {
  char *key;
  void *value;
  struct bucket *next;
} Bucket;

typedef struct {
  int key_count;
  int table_size;
  void (*free_value)(void *);
  Bucket **buckets;
} 


int create_table(Table ** table, int table_size, void (*free_value)(void *)){
  int iterate = 0;
  *table = malloc(sizeof(Table));

  if(table && table_size != 0) {
    (*table)->key_count = 0;
    (*table)->table_size = table_size;
    (*table)->free_value = free_value;
    (*table)->buckets = malloc(table_size * sizeof(Bucket));  /* Error is here */

    while(iterate < table_size)
      *table->buckets[iterate++] = NULL;
    return SUCC;
  }
  return FAIL;
}

2 Answers 2

3

By the look of your allocation:

(*table)->buckets = malloc(table_size * sizeof(Bucket));

It looks as though you are attempting to create space for table_size buckets and not table_size pointers to bucket. It the allocation should read:

(*table)->buckets = malloc(table_size * sizeof(Bucket*)); 

The error, I believe, is further down in the while loop. Operator -> has precedence over [] which has precedence over *, therefore you are actually saying *(table->buckets[iterate++]), and table is a pointer-pointer and does therefore not have a member called bucket.

Sign up to request clarification or add additional context in comments.

1 Comment

Note, the malloc error could have been avoided by using the idiom ptr = malloc( N * sizeof *ptr );
1

(Note: You're missing a Table; in your second typedef.

int create_table(Table ** table, int table_size, void (*free_value)(void *)){
  int iterate = 0;
  *table = malloc(sizeof(Table));

  if(table && table_size != 0) {

This isn't right. You should test table before you allocate memory, and then test *table.

    (*table)->key_count = 0;
    (*table)->table_size = table_size;
    (*table)->free_value = free_value;
    (*table)->buckets = malloc(table_size * sizeof(Bucket));  /* Error is here */

Here, you are allocating space for table_size number of Bucket, but assigning the memory to a pointer to pointer to Bucket. It looks like you want to allocate table_size number of pointers to Bucket.

    while(iterate < table_size)
      *table->buckets[iterate++] = NULL;

This is the same as *(table->buckets[iterate++]) which is obviously wrong. table is not a pointer to struct, *table is. This is where your real error is.


I would probably write something like this:

typedef struct {
  int key_count;
  int table_size;
  void (*free_value)(void *);
  Bucket **buckets;
} Table;

int create_table(Table **table, int table_size, void (*free_value)(void *))
{
  if (!table || table_size == 0) {
    return FAIL;
  }
  *table = malloc(sizeof(Table));
  if (*table) {
    (*table)->key_count = 0;
    (*table)->table_size = table_size;
    (*table)->free_value = free_value;
    (*table)->buckets = malloc(table_size * sizeof(Bucket *));
    if ((*table)->buckets) {
      int iterate = 0;
      while(iterate < table_size)
        (*table)->buckets[iterate++] = NULL;
      return SUCC;
    }
  }

  if (*table) {
    free ((*table)->buckets);
  }
  free (*table);
  return FAIL;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.