我一整天都试图绕过这个......
基本上,我有一个名为State的结构,它有一个名称,另一个名为StateMachine,带有名称,状态数组和添加的状态总数:
#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);
}
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因(阅读低C-fu/ruby/python/php的年份)我无法表达状态是状态数组的事实.上面的代码打印:
--> [0] state: ~
--> [1] state: Foo
--> [2] state: Bar
Run Code Online (Sandbox Code Playgroud)
第一个州增加了什么?
如果我在添加的第一个状态上malloc状态数组(例如state_machine = malloc(sizeof(temp));那么我得到第一个值而不是第二个值.
有什么建议吗?
这是一个C问题.我正在使用gcc 4.2.1编译样本.
看起来你没有为机器中的状态分配空间而不是第一个.
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)); // This bit here only allocates space for 1.
return temp;
}
Run Code Online (Sandbox Code Playgroud)
你可能最好在状态机结构中放置一个固定大小的状态数组.如果这不合适,你将不得不重新分配并移动整个集合或分配块并跟踪当前长度,或制作链表.
顺便说一句,init,foo和bar永远不会被使用.
编辑:我建议的内容如下:
#define MAX_STATES 128 // Pick something sensible.
typedef struct StateMachine {
const char * name;
int total_states;
State *states[MAX_STATES];
} StateMachine;
Run Code Online (Sandbox Code Playgroud)
看起来你想在每个状态机中拥有可变数量的状态,但是你错误地分配了内存.在create_state_machine,这一行:
temp->states = malloc(sizeof(struct State));
Run Code Online (Sandbox Code Playgroud)
分配单个State对象,而不是指针数组(这是您使用它的方式).
有两种方法可以改变这种情况.
states为State states[<some-fixed-size>];但是你不能拥有超过固定数量的状态.states,因此您可以跟踪它以及使用的数量(这是total_states用于的内容).后者看起来像这样:
#include <stdlib.h>
#include <string.h>
typedef struct
{
const char *name;
} State;
typedef struct
{
const char *name;
int total_states;
int states_capacity;
State *states;
} StateMachine;
StateMachine *create_state_machine(const char *name)
{
StateMachine *temp = malloc(sizeof(StateMachine));
memset(temp, 0, sizeof(*temp));
temp->name = name;
temp->states_capacity = 10;
temp->states = malloc(sizeof(State) * temp->states_capacity);
return temp;
}
State *add_state(StateMachine *machine, const char *name)
{
if (machine->total_states == machine->states_capacity)
{
// could grow in any fashion. here i double the size, could leave
// half the memory wasted though.
machine->states_capacity *= 2;
machine->states = realloc(
machine->states,
sizeof(State) * machine->states_capacity);
}
State *state = (machine->states + machine->total_states);
state->name = name;
machine->total_states++;
return state;
}
Run Code Online (Sandbox Code Playgroud)