Initializing a C Structure with Pointer to Pointer

I am working on creating a hash table implementation for the assignment. I have defined my hash table as a structure like this:

typedef struct hashtable {
  int size;
  int entries;
  int table*;   // pointer to table. Each entry will point to linked list 
                // of key-value nodes 
} hashtable;

      

I need to initialize a hashtable structure in a method using double pointers like:

void init(hashtable** ht) {
...
}

      

I wrote a basic implementation below:

#include <stdio.h>
#include <stdlib.h>

typedef struct hashtable {
  int size;
  int entries;
  int table*;   // pointer to table. Each entry will point to linked list 
                // of key-value nodes 
} hashtable;

void init(hashtable**);

void init(hashtable** ht) {
    *ht = (hashtable *) malloc( sizeof(hashtable) );
    *ht->size = 3;
}

int main(){

  hashtable *t = NULL;
  init(&t);

  printf("t.size: %i", t->size);
}

      

However, I keep getting the following compilation error:

ll.c:19:8: error: member reference base type 'hashtable *' (aka 'struct hashtable *') is not a
      structure or union
    *ht->size = 3;
     ~~^ ~~~~
1 error generated.

      

So, the following confuses me: 1. I'm not sure how to create a new structure in the init function when passing a pointer to a pointer. 2. After selecting the structure, how can I change the attributes of the structure element?

+3


source to share


5 answers


It's just an operator priority issue.

Compiler process -> before *. So it tries to access an element of size struct hashtable ** which is not possible.



The code compiles if you change * ht-> size from (* ht) -> size.

+2


source


There are 2 errors in the code:



  • int table*

    int *table

    - Declare a pointer to an integer

  • * ht-> size (*ht)->size

    - > - Import parentheses if you are not sure about operator precedence

+2


source


The problem is

->

has higher precedence than *

C as you can see from here

using priority rules *ht->size

translates to * (ht-> size). This should clearly state the reason why you are getting the error. Another way to see this is

*(ht->size)=(*(*ht).size)

      

Fix it with parentheses like this: (*ht)->size

There hashtable

is another problem in the definition :   int table*;

will not compile. Use int *table;

instead to declare pointer to int

?

+1


source


This is a good start, and the others are major problems in your code. However, I would suggest a minor tweak:

#include <stdio.h>
#include <stdlib.h>

typedef struct hashtable {
  int size;
  int entries;
  int table*;   // pointer to table. Each entry will point to linked list 
                // of key-value nodes 
} hashtable;


// note: freeing the hashtable is a caller responsibility!
hashtable *new_hashtable() {
    hashtable *ht = malloc( sizeof(hashtable) );
    ht->size = 3; // since ht is only a single pointer, no need for (*ht)->foo 

    return ht;
}

int main(){

  hashtable *ht = new_hashtable();

  printf("ht.size: %i", ht->size);

  free(ht);
}

      

+1


source


Thanks everyone for the quick response. For future reference here, you can quickly update the source code with the solutions:

#include <stdio.h>
#include <stdlib.h>

typedef struct hashtable {
  int size;     // size of hash table
  int entries;  // number of slots allocated in table
  int *table;   /* pointer to table. Each entry will point to linked list
                  of key-value nodes */
} hashtable;

void init(hashtable**);

void init(hashtable** ht) {
    *ht = (hashtable *) malloc( sizeof(hashtable) );
    (*ht)->entries = 0;
    (*ht)->size = 3; //replace this with better init size, ideally a prime number
    (*ht)->table = malloc( (*ht)->size  * sizeof(int));
}

int main(){

  hashtable *t = NULL;
  init(&t);
  t->table[2] = 3;

  printf("t.size: %i \n", t->size);
  printf("t.arr:[2] %i \n", t->table[2]);
  free(t);
}

      

0


source







All Articles