The problem is that you’re freeing the sym
, then trying to access a value from the (now-freed) data: sym->next
.
You probably want something like this for the inner loop:
struct symbol *next_sym = NULL;
for(sym = st[i]; sym != NULL; ) {
next_sym = sym->next;
free(sym);
sym = next_sym;
}