我有一个关于为结构创建和分配空间的问题,以及什么是更好的"这样做的方式。
让我们说我们有一堆参数,基于它们我们想要创建一个结构。不直接存储所有参数,但以某种方式处理它们并存储值。
示例:
typedef struct {
int op;
int res;
} Result;
int operation = 0; // 0 = addition, 1 = multiplication
int a = 2, int b = 3;
Result r;
r.op = operation;
if (operation == 0) {
r.res = a+b;
else if(operation == 1) {
r.res = a*b;
else {
...etc...
}
这些操作可能比这更复杂,并且可能有更多参数定义最终结构。 所以我想创建一个函数
create_structure(arg1, arg2, arg3, ..., argn) {
switch(arg1) {
case 0: struct_function0(arg1, arg2, arg3, ..., argn); break;
case 1: struct_function1(arg1, arg2, arg3, ..., argn); break;
...
case m: struct_functionm(arg1, arg2, arg3, ..., argn); break;
}
}
并且所有这些函数可以具有与“create_structure”类似的结构,并且将形成“函数创建树”,其中我们总是基于参数选择一个分支,直到我们到达最终将创建我们的结构的一些函数。 我们也想要" root"树的返回指向存储此结构的内存位置。
问题是如何从" leaf"返回创建的结构。函数创建树。
第一个选项是始终从内部函数返回结构,然后在树的根中为该结构分配内存并memcpy所有内容:
MyStruct* create_structure(arg1, arg2, arg3, ..., argn) {
MyStruct s;
switch(arg1) {
case 0: s = struct_function0(arg1, arg2, arg3, ..., argn); break;
case 1: s = struct_function1(arg1, arg2, arg3, ..., argn); break;
...
case m: s = struct_functionm(arg1, arg2, arg3, ..., argn); break;
}
MyStruct* p_s = malloc(sizeof(MyStruct));
memcpy(p_s, &s, sizeof(MyStruct));
return p_s
}
另一种可能性是指向根中的结构的指针,对其进行mallocing,然后将其作为参数发送给所有"分支"这棵树喜欢这个
MyStruct* create_structure(arg1, arg2, arg3, ..., argn) {
MyStruct* p_s = malloc(sizeof(MyStruct));
switch(arg1) {
case 0: struct_function0(p_s, arg1, arg2, arg3, ..., argn); break;
case 1: struct_function1(p_s, arg1, arg2, arg3, ..., argn); break;
...
case m: struct_functionm(p_s, arg1, arg2, arg3, ..., argn); break;
}
return p_s;
}
在第二个变体中,我们将参数p_s传递给树中的所有函数,直到我们到达叶子。
有一个可能的第三种选择,其中malloc可以在树的叶子中。
首选哪种可能性?还有其他选择吗?
答案 0 :(得分:3)
我会让调用者决定如何分配MyStruct,以便调用者知道是否或如何解除分配。
void create_structure(MyStruct *s, arg1, arg2, arg3, ..., argn) {
switch(arg1) {
case 0: struct_function0(s, arg1, arg2, arg3, ..., argn); break;
case 1: struct_function1(s, arg1, arg2, arg3, ..., argn); break;
}
}
MyStruct s;
create_structure(&s, 1,2,3);
或
MyStruct *s2 = malloc(sizeof *s2);
create_structure(s2, 1,2,3);
free(s2);
答案 1 :(得分:2)
实际上你根本不需要malloc。一种可能性是将指向struct的指针传递给所有函数
void create_structure(MyStruct* s, arg1, ...)
{
...
}
MyStruct p_s;
create_structure(&s, arg1, arg2, ...);
如果结构尺寸较小,您也可以返回结构的副本,然后不会进行大量操作。
MyStruct create_structure(arg1, arg2, arg3, ..., argn) {
MyStruct p_s;
switch(arg1) {
case 0: p_s = struct_function0(arg1, arg2, arg3, ..., argn); break;
case 1: p_s = struct_function1(arg1, arg2, arg3, ..., argn); break;
...
case m: p_s = struct_functionm(arg1, arg2, arg3, ..., argn); break;
}
return p_s;
}