I’ve been trying to wrap my head around this the whole day…
Basically, I have a struct called State that has a name and another one called StateMachine with a name, an array of states and total number of states added:
#include <stdio.h>
#include <stdlib.h>
typedef struct State {
const char * name;
} State;
typedef struct StateMachine {
const char * name;
int total_states;
State ** states;
} StateMachine;
StateMachine * create_state_machine(const char* name) {
StateMachine * temp;
temp = malloc(sizeof(struct StateMachine));
if (temp == NULL) {
exit(127);
}
temp->name = name;
temp->total_states = 0;
temp->states = malloc(sizeof(struct State));
return temp;
}
void destroy_state_machine(StateMachine* state_machine) {
free(state_machine);
}
State * add_state(StateMachine* state_machine, const char* name) {
State * temp;
temp = malloc(sizeof(struct State));
if (temp == NULL) {
exit(127);
}
temp->name = name;
state_machine->states[state_machine->total_states]= temp;
state_machine->total_states++;
return temp;
}
int main(int argc, char **argv) {
StateMachine * state_machine;
State * init;
State * foo;
State * bar;
state_machine = create_state_machine("My State Machine");
init = add_state(state_machine, "Init");
foo = add_state(state_machine, "Foo");
bar = add_state(state_machine, "Bar");
int i = 0;
for(i; i< state_machine->total_states; i++) {
printf("--> [%d] state: %s\n", i, state_machine->states[i]->name);
}
}
For some reason (read low C-fu / years of ruby/python/php) I’m unable to express the fact that states is an Array of State(s). The above code prints:
--> [0] state: ~
--> [1] state: Foo
--> [2] state: Bar
What happened with the first state added?
If I malloc the states array on the first state added (e.g. state_machine = malloc(sizeof(temp)); then I get the first value but not the second.
Any advices?
This is a C question. I’m using gcc 4.2.1 to compile the sample.
It looks like you’re not allocating space for your states in the machine past the first one.
You’re probably better off putting an array of states of fixed size in the state machine struct. If that’s not okay, you’ll have to realloc and move the whole set around or allocate chunks and keep track of the current length, or make a linked list.
Incidentally, init, foo, and bar never get used.
Edit: What I’m suggesting looks like this: