Removed memory leaks, minor bug and security fixes
This commit is contained in:
parent
6449cb0374
commit
289de54e7e
1 changed files with 61 additions and 15 deletions
76
main.c
76
main.c
|
|
@ -4,6 +4,7 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define WORD 32
|
||||
#define TRANSFORM_TABLE_MAX_RAND 4294967296
|
||||
|
|
@ -44,6 +45,8 @@ typedef struct
|
|||
// Returns -1 when the hashtable is full
|
||||
int get_empty_hashtable_slot(shash_hashtable_t *hashtable)
|
||||
{
|
||||
assert(hashtable != NULL);
|
||||
|
||||
for (int i = 0; i < hashtable->table_size; i++)
|
||||
{
|
||||
if (hashtable->hash_table[i].key == 0)
|
||||
|
|
@ -53,12 +56,17 @@ int get_empty_hashtable_slot(shash_hashtable_t *hashtable)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void shash_init_hashtable(shash_hashtable_t *hashtable, unsigned int table_size)
|
||||
int shash_init_hashtable(shash_hashtable_t *hashtable, unsigned int table_size)
|
||||
{
|
||||
// Initialize the RNG to a non-constant value, to make the output less pseudo random
|
||||
srand(time(NULL));
|
||||
|
||||
// Create a random transformation table
|
||||
srand(0);
|
||||
// srand(time(NULL));
|
||||
unsigned int *table = malloc((CHAR_MAX - CHAR_MIN) * sizeof(int));
|
||||
if(table == NULL)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CHAR_MAX - CHAR_MIN; i++)
|
||||
{
|
||||
|
|
@ -67,13 +75,20 @@ void shash_init_hashtable(shash_hashtable_t *hashtable, unsigned int table_size)
|
|||
hashtable->transformation_table = table;
|
||||
|
||||
hashtable->hash_table = malloc(table_size * sizeof(shash_table_element_t));
|
||||
if(hashtable->hash_table == NULL)
|
||||
{
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
memset(hashtable->hash_table, 0, table_size * sizeof(shash_table_element_t));
|
||||
|
||||
hashtable->table_size = table_size;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
unsigned int shash_hash(char *key, unsigned int len, shash_hashtable_t *hashtable)
|
||||
{
|
||||
assert(hashtable != NULL);
|
||||
|
||||
if (SIMULATE_COLLISIONS == 1)
|
||||
{
|
||||
return SIMULATED_COLLISION_HASH;
|
||||
|
|
@ -91,37 +106,48 @@ unsigned int shash_hash(char *key, unsigned int len, shash_hashtable_t *hashtabl
|
|||
|
||||
int shash_set(char *key, unsigned int len, void *data, shash_hashtable_t *hashtable)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(data != NULL);
|
||||
assert(hashtable != NULL);
|
||||
|
||||
unsigned int slot = shash_hash(key, len, hashtable);
|
||||
|
||||
//Loop to the end of the linked list
|
||||
while(hashtable->hash_table[slot].encountered_collision != 0){
|
||||
slot = hashtable->hash_table[slot].next_key_location;
|
||||
// Loop to the end of the linked list
|
||||
while (hashtable->hash_table[slot].encountered_collision != 0 && strcmp(hashtable->hash_table[slot].key, key) != 0)
|
||||
{
|
||||
slot = hashtable->hash_table[slot].next_key_location;
|
||||
}
|
||||
|
||||
shash_table_element_t table_element = {
|
||||
.key = key,
|
||||
.data = data};
|
||||
shash_table_element_t table_element =
|
||||
{
|
||||
.key = strndup(key, len),
|
||||
.data = data};
|
||||
|
||||
if (hashtable->hash_table[slot].key == 0)
|
||||
{
|
||||
hashtable->hash_table[slot] = table_element;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int empty_slot = get_empty_hashtable_slot(hashtable);
|
||||
if (empty_slot != -1)
|
||||
{
|
||||
hashtable->hash_table[slot].encountered_collision = 1;
|
||||
hashtable->hash_table[slot].encountered_collision = 1;
|
||||
hashtable->hash_table[slot].next_key_location = empty_slot;
|
||||
hashtable->hash_table[empty_slot] = table_element;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//hashtable full
|
||||
// hashtable full
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *shash_get(char *key, unsigned int len, shash_hashtable_t *hashtable)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(hashtable != NULL);
|
||||
|
||||
unsigned int slot = shash_hash(key, len, hashtable);
|
||||
|
||||
while (strcmp(hashtable->hash_table[slot].key, key) != 0)
|
||||
|
|
@ -141,6 +167,21 @@ void *shash_get(char *key, unsigned int len, shash_hashtable_t *hashtable)
|
|||
return hashtable->hash_table[slot].data;
|
||||
}
|
||||
|
||||
void shash_destroy_hashtable(shash_hashtable_t *hashtable)
|
||||
{
|
||||
assert(hashtable != 0);
|
||||
|
||||
for(int i = 0; i < hashtable->table_size; i++)
|
||||
{
|
||||
if(hashtable->hash_table[i].key != NULL)
|
||||
{
|
||||
free(hashtable->hash_table[i].key);
|
||||
}
|
||||
}
|
||||
free(hashtable->transformation_table);
|
||||
free(hashtable->hash_table);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Initialize an empty hashtable
|
||||
|
|
@ -148,11 +189,16 @@ int main(void)
|
|||
shash_init_hashtable(&hashtable, 100);
|
||||
|
||||
// Store some data
|
||||
shash_set("FOO", 3, "Hello, World", &hashtable);
|
||||
|
||||
shash_set("FOO", 3, "Hello", &hashtable);
|
||||
shash_set("BAR", 3, "World!", &hashtable);
|
||||
|
||||
// And retrieve it
|
||||
char *retrieved_val = shash_get("FOO", 3, &hashtable);
|
||||
printf("Stored string %s\n", retrieved_val);
|
||||
char *retrieved_foo = shash_get("FOO", 3, &hashtable);
|
||||
char *retrieved_bar = shash_get("BAR", 3, &hashtable);
|
||||
printf("%s, %s\n", retrieved_foo, retrieved_bar);
|
||||
|
||||
// Destroy the hashtable
|
||||
shash_destroy_hashtable(&hashtable);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue