I am trying to use an array of structs to create a symbol table. This is what I have so far, but I am having trouble allocating memory in the create function, is what I have so far correct?
I want something like this as my final result for arr { {"sym1"; 1}, {"sym2"; 2}, {"sym3"; 3} }
struct str_id {
char* s;
int id;
}
struct symbol_table {
int count;
struct str_id** arr;
}
struct symbol_table *symbol_table_create(void) {
struct symbol_table *stt = malloc(sizeof(struct symbol_table));
stt->count = 1;
stt->arr = malloc(sizeof(struct str_id*) * stt->count);
return stt;
}
s
and str_id
).str_id
is an abbreviation for struct_id
(or string_id
) - which is a bad name because it's already immediately obvious that it's a struct
(or contains a string).calloc
and malloc
's return values to NULL
. This can be done with if( some_pointer ) abort()
.
assert( some_pointer )
because assertions are only enabled in debug builds, use abort
instead as it signifies abnormal program termination compared to exit
.size_t
parameter so consumers can specify the size of the symbol table.size_t
(e.g. array indexers). Never use int
for this!struct
definition.array-of-pointers-to-structs
and not just an array-of-structs
? In this case you can use inline structs and use a single allocation for the array, instead of allocating each member separately.struct symbol_table_entry {
char* symbolText;
int id;
};
struct symbol_table {
size_t count;
struct symbol_table_entry** entries;
};
struct symbol_table* create_symbol_table( size_t count ) {
struct symbol_table* stt = malloc( sizeof(struct symbol_table) );
if( !stt )
{
abort();
}
stt->count = count;
stt->entries = calloc( count, sizeof(struct symbol_table_entry) );
if( !stt->entries ) {
free( stt );
abort();
}
// Note that calloc will zero-initialize all entries of the array (which prevents debuggers showing garbage string contents) so we don't need to do it ourselves.
return stt;
}
void destroy_symbol_table( struct symbol_table* stt, bool free_strings ) {
if( stt->entries ) {
if( free_strings ) {
for( size_t i = 0; i < stt->count; i++ ) {
free( stt->entries[i]->symbolText );
}
}
free( stt->entries );
}
free( stt );
}