I'm working on creating a hash table implementation for an assignment. I've defined my hashtable as struct as follows:
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 have to initialize the hashtable struct in a method using double pointers, eg:
void init(hashtable** ht) {
...
}
I've written 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 compile 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 I'm confused by the following: 1. I'm not sure how to create a new struct in the init function when being passed a pointer to pointer. 2. After allocating the struct, how do I modify the struct member attributes?
You have 2 errors in your code :
int table*
--> int *table
- Declare pointer to integer
*ht->size --> (*ht)->size
- Imp to put brackets when you are not sure of operator precedence
This is just a operator precedence problem.
The compiler processes -> before the *. Therefore, it tries to access the size member of struct hashtable ** which is not possible.
The code compiles if you exchange *ht->size with (*ht)->size.
The problem is that
->
has higher precedence than *
in C as you can see from here
using precedence rules *ht->size
translates to *(ht->size). That should make clear the reason why you get the error. Another way to see it is
*(ht->size)=(*(*ht).size)
Fix this using parenthesis as follows: (*ht)->size
There is another issue in the definition of hashtable
: int table*;
won't compile. Use int *table;
instead to declare a pointer to int
?
That's a good start, and others have addresses the primary issues 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);
}
Thanks all for the quick response. For future reference, here's a quick update of the original code with 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);
}
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.