在C中创建和返回结构

时间:2018-06-01 11:16:48

标签: c c99

我有一个关于为结构创建和分配空间的问题,以及什么是更好的"这样做的方式。

让我们说我们有一堆参数,基于它们我们想要创建一个结构。不直接存储所有参数,但以某种方式处理它们并存储值。

示例:

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可以在树的叶子中。

首选哪种可能性?还有其他选择吗?

2 个答案:

答案 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;
}