具有未知大小的结构体数组的结构体
我一整天都在试图解决这个问题......
,我有一个名为 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);
}
}
基本上 出于某种原因(阅读低 C-fu / 多年的 ruby/python/php)我无法表达 states 是一个状态数组的事实。上面的代码打印:
--> [0] state: ~
--> [1] state: Foo
--> [2] state: Bar
添加的第一个状态发生了什么?
如果我在添加的第一个状态上 malloc 状态数组(例如 state_machine = malloc(sizeof(temp)); 那么我得到第一个值,但不是第二个值。
有什么建议吗?
这是一个 C 问题。我正在使用 gcc 4.2。 1 编译示例。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看起来您没有为机器中第一个状态之后的状态分配空间。
您最好将固定大小的状态数组放入状态机结构中。如果这不行,您将必须重新分配并移动整个集合,或者分配块并跟踪当前长度,或者创建一个链接列表。
顺便说一下,init、foo 和 bar 从来没有被使用过。
编辑:我的建议看起来像这样:
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:
看起来您希望在每个状态机中拥有可变数量的状态,但您分配的内存不正确。在
create_state_machine
中,这一行:分配单个
State
对象,而不是指针数组(这就是您使用它的方式)。有两种方法可以改变这种情况。
states
声明为State states[];
但这样你就不能拥有超过固定数量的状态。states
分配了多少存储空间,以便您可以跟踪该存储空间以及使用了多少存储空间(即正在使用的total_states
为了)。后者看起来像这样:
It looks like you want to have a variable number of states in each state machine, but you are allocating the memory incorrectly. In
create_state_machine
, this line:Allocates a single
State
object, not an array of pointers (which is how you are using it).There are two ways you could change this.
states
asState states[<some-fixed-size>];
but then you cant ever have more than a fixed number of states.states
, so you can keep track of that as well as how much is used (which is whattotal_states
is being used for).The later would look something like this:
在你的 add_state 函数内部:
应该是
但是,即使改变了,我仍然得到正确的输出:
也许你的代码没有任何问题。我正在使用 gcc 版本 4.4.3
Inside of your add_state function:
should be
However, even when this is changed, I still get the proper output:
Perhaps there's nothing wrong with your code. I'm using gcc version 4.4.3
将创建一个状态数组的数组。
我还没有如实阅读整个解决方案(必须运行),但您提到想要一组状态 - 您是否可能想做:
或者
相反?只是供大家思考,很可能这不是你的问题,因为我没有完全阅读它:p
will create an array of state arrays.
I haven't read through the whole solution truthfully (gotta run), but you mentioned wanting an array of states - did you possibly want to do:
or
instead? Just food for thought, chances are it wasn't your problem since I didn't fully read it :p
您犯了一个概念错误:
确实,您可以将状态视为指向 State 对象的指针数组,但您只为一种状态分配空间。
当你这样做时:
如果total_states大于零,你就做错了,因为你指向未分配的内存段(我想知道为什么你没有得到SEGFAULT)。要以这种方式存储动态数量的状态,您需要一个链接列表,或者调用 realloc 您添加的每个状态(但这不是一个好主意)。使用不同的 malloc 调用分配的内存不是连续的。
You're doing a conceptual error:
It's true that you can consider states like an array of pointer to State object, but you are allocating space for just one state.
When you do:
you are doing something wrong if total_states is greater than zero because you are pointing to memory segments that are not been allocated (I'm wondering why you don't get a SEGFAULT). To store a dynamic number of State this way you need a linked list, or to call realloc every state you add(but that's not a good idea). The memory you are allocating with different malloc calls isn't continuous.