I want to make a hashtable in c, where the keys are integers and the values are strings
I have a 2D char array in a struct, as follows in hashtable.h file:
#ifndef hashtable
#define hashtable
// define the maxmium size
#define INITIAL_SIZE 5
#define LOAD_FACTOR 0.7
typedef struct hashtable
{
int* keyArray[INITIAL_SIZE];
char* valueArray[INITIAL_SIZE][101]; // strings have maximum of 100 chars
bool isActiveArray[INITIAL_SIZE]; // for deleting elements
int count;
int capacity;
double loadFactor;
// true: linear probing, false: quadratic probing
bool collisionHandler;
} table;
#endif
I am trying to initialize the values of the arrays outside of the struct, like so
void initTable(table* p) {
// constructor
p->count = 0;
p->capacity = INITIAL_SIZE;
p->loadFactor = LOAD_FACTOR;
p->collisionHandler = true;
p->keyArray = {NULL};
p->valueArray = {{NULL}};
p->isActiveArray = {false};
}
however i receive these errors:
In file included from HashTable.c:22:0:
functions.h: In function 'initTable':
functions.h:85:16: error: expected expression before '{' token
p->keyArray = {NULL};
^
functions.h:86:18: error: expected expression before '{' token
p->valueArray = {{NULL}};
^
functions.h:87:21: error: expected expression before '{' token
p->isActiveArray = {false};
note: p is a pointer to my table struct
I want to know how to make a 2D array of all NULL values in the char* array, like
{{NULL}, {NULL}, {NULL}}
also to use for comparison later on like trying to insert a value into the valueArray, and checking if null
I also want to make the keyArray, the int* list to be like {NULL, NULL, NULL} instead of a random memory address so I can easily check for a NULL pointer, and then replace it with a pointer to an int when making a new key/value pair
CodePudding user response:
To initialise a region of memory (an instance of a struct either as a local variable or from the heap) where most elements are NULL (or false), simply use:
table t;
memset( &t, 0, sizeof t );
Then go on to initialise the few elements that are not NULL or 0 or false:
#include <assert.h>
void initTable( table* p ) {
assert( p != NULL );
memset( p, 0, sizeof *p );
p->capacity = INITIAL_SIZE;
p->loadFactor = LOAD_FACTOR;
p->collisionHandler = true;
}
Kudos for using "include guards" in the header file. More conventional would be using an UPPERCASE token, and perhaps even a suffix...
#ifndef HASHTABLE_H
One further suggestion:
char* valueArray[INITIAL_SIZE][100 1];
makes it clear (to me) that the '\0' is being considered in this allocation.
CodePudding user response:
Initializing the values of an array using the {
}
brace syntax will only work in a declaration. You cannot use that syntax after an array has already been declared.
If you really want to use the brace syntax after an array has already been declared, one thing you can do is declare another temporary array of the same type and size and initialize it with the brace syntax, and then copy the temporary array to the original array using memcpy
, for example like this:
#include <stdio.h>
#include <string.h>
int main( void )
{
//declare array without initializing it
int arr[5];
//create temporary array and initialize it with brace syntax
const int temp[5] = { 1, 2, 3, 4, 5 };
//copy temporary array to original array
memcpy( arr, temp, sizeof arr );
//print contents of original array
for ( int i = 0; i < 5; i )
{
printf( "%d\n", arr[i] );
}
}
This program will output the numbers 1
to 5
.
Using this method, your function initTable
would look like this:
void initTable( table* p ) {
// constructor
p->count = 0;
p->capacity = INITIAL_SIZE;
p->loadFactor = LOAD_FACTOR;
p->collisionHandler = true;
const int* temp_keyArray[INITIAL_SIZE] = { NULL };
memcpy( p->keyArray, temp_keyArray, sizeof temp_keyArray );
const char* temp_valueArray[INITIAL_SIZE][101] = { NULL };
memcpy( p->valueArray, temp_valueArray, sizeof temp_valueArray );
const bool temp_isActiveArray[INITIAL_SIZE] = { false };
memcpy( p->isActiveArray, temp_isActiveArray, sizeof temp_isActiveArray );
}
However, since you want to initialize all array elements to zero, there is a simpler solution. You can use the function memset
to set all bytes of the array to zero:
void initTable( table* p ) {
// constructor
p->count = 0;
p->capacity = INITIAL_SIZE;
p->loadFactor = LOAD_FACTOR;
p->collisionHandler = true;
memset( p->keyArray, 0, sizeof *p->keyArray );
memset( p->valueArray, 0, sizeof *p->valueArray );
memset( p->isActiveArray, 0, sizeof *p->isActiveArray );
}
Or, as already pointed out in the other answer by someone else, you can set all bytes of the entire struct hashtable
to zero using memset
and afterwards only set the values of the individual members of the struct
which are not supposed to be zero.