I'm writing an implementation for Hash Tables in C, but I'm getting bogged down with some stuff. I have written the functions and the data definitions in a separate file.
I have the header file Hashes.h which looks like:
#ifndef HASHES_H_INCLUDED
#define HASHES_H_INCLUDED
int accumulation(long int);
struct entry_s {
char *key;
char *value;
struct entry_s *next;
};
typedef struct entry_s entry_t;
struct hashtable_s {
int size;
struct entry_s **table;
};
typedef struct hashtable_s hashtable_t;
hashtable_t * ht_create( int );
#endif // HASHES_H_INCLUDED
and I have the Hashes.c file which looks like:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "Hashes.h"
/*Creates the hashtable*/
hashtable_t *ht_create( int size ) {
hashtable_t * hashtable = NULL;
int i;
if( size < 1 ) return NULL;
/* Allocate the table itself. */
if ( ( hashtable = malloc( sizeof( hashtable_t ) ) ) == NULL ) {
return NULL;
}
/* Allocate pointers to the head nodes. */
if ( ( hashtable->table = malloc( sizeof( entry_t * ) * size ) ) == NULL ) {
return NULL;
}
for( i = 0; i < size; i++ )
{
hashtable->table[i] = NULL;
}
hashtable->size = size;
return hashtable;
}
int accumulation (long int x)
{
int hash = 0;
int i = 0;
while (x != 0)
{
hash += pow(33, i) + x % 10;
x /= 10;
}
return hash;
}
and in the main I have :
#include <stdio.h>
#include <stdlib.h>
#include "Hashes.h"
int main()
{
hashtable_t* myHashTable = ht_create(10000);
return 0;
}
I compiled all the files with no error or warning, but when I run the program I receive the error "Undefined reference to 'ht_create'".
If some one has a clue I would deeply appreciate that.
P.S.: I am using CodeBlocks IDE.
Related
I have created a struct:
typedef struct _POOL
{
int size;
void* memory;
}Pool;
and have then allocated space in the system memory for that structure but would like to return a pointer to the beginning of the allocated memory. I tried just returning the variable but got an error.
int main(void)
{
Pool* allocatePool(int n);
{
Pool *n = malloc(sizeof *n);
return n;
}
}
It seems you mean something like the following
#include <stdlib.h>
typedef struct _POOL
{
int size;
void* memory;
}Pool;
Pool * allocatePool( int n )
{
Pool *p = malloc( sizeof( Pool ) );
if ( p != NULL )
{
p->size = 0;
p->memory = malloc( sizeof( n ) );
if ( p->memory != NULL ) p->size = n;
}
return p;
}
int main(void)
{
int n = 10;
Pool *p = allocatePool( int n );
//...
if ( p != NULL ) free( p->memory );
free( p );
}
The function malloc is not declared because you missed to include the respective header stdlib.h. Thus, the compiler assumes an implicit declaration with a return type of int.
#include <stdio.h>
#include <stdlib.h>
int main()
{
typedef struct _POOL
{
int size;
void* memory;
} Pool;
Pool *p=(Pool*) malloc(sizeof(Pool));
return 0;
}
Here p is a pointer to the (first byte of the) allocated memory.
Code:
struct bunchofdata
{
int i;
void *dllist[i];
int spltq[i];
pthread_t tlist[i];
};
Errormsg:
error: āiā undeclared here (not in a function)
void *dllist[i];
^
I can't understand why this doesn't work.
In addition to pikkewyn's answer, another way to implement this is to use Flexible Array Member
This makes it easier to manage than allocating members separately.
#include <stdio.h>
#include <stdlib.h>
typedef int pthread_t;
struct data
{
void *dl;
int spltq;
pthread_t thread;
};
struct bunchofdata
{
int i;
struct data data_list[];
};
struct bunchofdata * data_factory(int size)
{
struct bunchofdata * ret = malloc(sizeof(struct bunchofdata)
+size*sizeof(struct data));
/* fill in the members here*/
ret->i=size;
return ret;
}
int main(void) {
struct bunchofdata *data10=data_factory(10);
data10->data_list[9].spltq=0;
printf("data10->data_list[9].spltq=%d",data10->data_list[9].spltq);
free(data10)
return 0;
}
You can use sth like this, although since each field of your structure is array it might be nicer to have array of such structs:
#include <malloc.h>
#include <pthread.h>
struct bunchofdata
{
int i;
void** dllist;
int* spltq;
pthread_t* tlist;
};
struct anotherbunchofdata
{
int i;
void* dll;
int spltq;
pthread_t tlist;
};
void init_bunchofdata( int size, struct bunchofdata* bd )
{
bd->i = size;
bd->dllist = malloc( size * sizeof( void* ) );
bd->spltq = malloc( size * sizeof( int ) );
bd->tlist = malloc( size * sizeof( pthread_t ) );
}
void free_bunchofdata( struct bunchofdata* bd )
{
free( bd->dllist );
free( bd->spltq );
free( bd->tlist );
}
int main()
{
struct bunchofdata bd;
init_bunchofdata( 5, &bd );
free_bunchofdata( &bd );
return 0;
}
I have a program in C that creates a hash table. I want to know what it is, but I am unsure how to print it out or display it. I have pasted the program below. I am rather new to hash tables so any help would be greatly appreciated!
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define TABLE_SIZE 7
#define NUM_INPUTS 7
int hash( char *s )
/* Note, this is a horrible hash function. It's here for
instructional purposes */
{
return strlen( s ) % TABLE_SIZE ;
}
typedef struct entry
{
char *key;
int val;
struct entry *next;
} entry;
entry* table[ TABLE_SIZE ] = { NULL };
void insert( char *s, int v )
/* this insert is NOT checking for duplicates. :/ */
{
int h = hash( s );
entry *t = (entry*) malloc( sizeof( entry ));
t->key = s;
t->val = v;
t->next = table[h];
table[h] = t;
}
void clean_table()
{
entry *p, *q;
int i;
for( i=0; i<TABLE_SIZE; ++i )
{
for( p=table[i]; p!=NULL; p=q )
{
q = p->next;
free( p );
}
} // for each entry
} // clean_table
int main()
{
char* keyList[] = { "Jaga", "Jesse", "Cos", "Kate", "Nash", "Vera",
"Bob" };
int valList[] = { 24, 78, 86, 28, 11, 99, 38 };
int i;
for( i=0; i<NUM_INPUTS; ++i )
insert( keyList[i], valList[i] );
/* what does the table look like here? */
clean_table();
return( 0 );
}
As requested in the comments, a search function as desired would look like this:
int search(const char* key, int* out_val)
{
// Find the hash index into the table.
const int index = hash(key);
// Now do a linear search through the linked list.
for (struct entry* node = table[index]; node; node = node->next)
{
// If we find a node with a matching key:
if (strcmp(node->key, key) == 0)
{
// Output the value and return 1 for success.
*out_val = node->val;
return 1;
}
}
// We didn't find anything. Return 0 for failure.
return 0;
}
Here's an example of a simple Hash Table in C. It doesn't really do any error handling, so this is not at all suitable for production, but it should help to see an example of a working implementation. Here is another post helping someone work through a hash table implementation in C.
I am trying to take input from console and add it to hash table.
But I'm getting Segmentation fault 11.
So, I debugged the program using gdb-apple.
It is showing that I'm trying access memory I cannot, using the pointer variable.
I think it is something obvious, but I'm missing it
This is what the gdb is displaying
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000986 in CreateHashTable (size=200) at hashing.c:29
29 h->Table[i]->next = NULL;
Here is the code
Header File:
#define LOAD_FACTOR 20
#define INITIAL_SIZE 200
struct HashTable *CreateHashTable(int size);
int HashSearch(struct HashTable *h,int data);
int HashInsert(struct HashTable *h,int data);
int HashDelete(struct HashTable *h, int data);
void Rehash(struct HashTable *h);
int Hash(int data, int size);
struct ListNode
{
int key;
int data;
struct ListNode *next;
};
struct HashTableNode
{
int bcount;
struct ListNode *next;
};
struct HashTable
{
int tsize;
int count;
struct HashTableNode **Table;
};
Implementation file:
#include "hashing.h"
#include<stdio.h>
#include<stdlib.h>
struct HashTable *CreateHashTable(int size)
{
struct HashTable *h;
h = (struct HashTable *) malloc ( sizeof(struct HashTable) );
if(h == NULL)
{
printf("Memory Error");
return NULL;
}
h->tsize = (int) size/LOAD_FACTOR;
printf("h->tsize = %d",h->tsize);
h->count = 0;
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
if( h->Table == NULL )
{
printf("Memory Error");
return NULL;
}
int i;
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}
return h;
}
I would paste the rest of file, or Driver file, but I don't see it relevant.
Please tell me why I'm getting the segmentation fault 11
You allocated memory for array of pointers but you didn't allocate memory for members of this array.
for( i=0 ; i < (h->tsize) ; i++)
{
h->Table[i] = malloc(...); //put correct arguments here and check allocation
h->Table[i]->next = NULL;
h->Table[i]->bcount = 0;
}
Your problem is here:
struct HashTableNode **Table;
You want an array of nodes (not a 2d array), change to:
struct HashTableNode *Table;
also change
h->Table = malloc ( ( sizeof(struct HashTableNode **) ) * (h->tsize) );
to
h->Table = malloc(sizeof(struct HashTableNode) * h->tsize);
I think I want an array of pointers to nodes, don't I?
As pointed out by #WhozCraig, there is no reason for the additional level of indirection.
Example A (Pointer):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *a; /* pointer */
int i, n = 10;
a = malloc(n * sizeof(int)); /* space for 10 ints */
for (i = 0; i < n; i++) {
a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", a[i]);
}
free(a);
return 0;
}
Example B (Pointer to pointer):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int **a; /* pointer to pointer*/
int i, n = 10;
a = malloc(n * sizeof(int *)); /* space for 10 pointer to ints */
for (i = 0; i < n; i++) {
a[i] = malloc(sizeof(int)); /* space for 1 int */
*a[i] = i;
}
for (i = 0; i < n; i++) {
printf("%d\n", *a[i]);
free(a[i]);
}
free(a);
return 0;
}
As you can see both do the same thing, but the first one requires less memory and the code is cleaner.
One way to make it easy to remember is:
int * can hold an array
int ** can hold a table (NROWS * NCOLS)
int *** can hold an array of tables
I have this structure here:
typedef struct _open {
int x;
struct _open *next;
} *NODE;
And on my main function I declared this pointer:
NODE open = initOpen(size);
Here's the initOpen function:
NODE initOpen(int size) {
return (NODE)malloc(sizeof(struct _open)*size);
}
I this correct? can I access my array in the main function like: open[0] to open[9] ?
First of all, the way you are doing dynamically allocated array is wrong.
I'm not sure if you actually want the thing you wrote, which is linked list, or the thing you said, which is dynamically allocated array.
Below is how you should do dynamically allocated array. Hope it helps.
By doing so, you can add as many ints into the array as you want, before you run out of memory. And you can access the array using array notation but with a pointer first: darray->array[0]
Your linked list, however, can not be accessed with this syntax.
#include <stdio.h>
#include <stdlib.h>
#define INITSIZE 8
typedef struct dyarr{
int num;
int max;
int *array;
}arr;
arr* makeArr();
void add( arr*, int );
int main( int argc, char const *argv[] ){
int t;
arr* darray = makeArr();
while( scanf( "%d", &t ) != EOF ){
add( darray, t );
}
int i;
for( i = 0; i<darray->num; i++ ){
printf( "%d\n", darray->array[i] );
}
getchar();
return 0;
}
arr* makeArr(){
arr* A = malloc( sizeof( arr ) );
A->max = MAXSIZE;
A->num = 0;
A->array = malloc( sizeof( int )*A->max );
return A;
}
void add( arr* a, int i ){
if( a->num == a->max ){
a->max *= 2;
a->array = realloc( a->array, a->max );
}
a->array[a->num++] = i;
}
First of all, you should respect some conventions:
typedef struct node {
int x;
struct node *next;
} *nodePtr;
Second, what is the usage of the parameter size ?
According to me the right way to allocate a new nodePtr is:
nodePtr initNodePtr() {
return (nodePtr)malloc(sizeof(struct node));
}
Also dont forget to release memory after usage:
nodePtr node = initNodePtr();
...
...
free(node); //should be wrapped in a function to respect design.
To Create an array of structure, you should do the following:
typedef struct {
int x;
node* next;
} node;
int main() {
node* nodeArray = (node*)malloc(sizeof(node)*50); // 50 = size of your array
...
// do whatever you want
...
free(nodeArray);
}
Not tested, let me know if errors.