如何提示用户配置in out参数?

How to hint users to do the allocation in out parameter?

假设我有一些像这样的纯 C 代码。

这不是真正的代码,只是一个例子。

struct Param {
  struct InParam {
    int a;
    int b;
  } in; 
  struct OutParam {
    int *c;
  } out;
};

void MakeArray(struct Param *param) {
  // just for filling the output param
  for (int i = 0; i < param->in.a; ++i) {
    param->out.c[i] = param->in.b;
  }
}

int main() {
  int *p = NULL;
  special_memory_alloc(&p, sizeof(int) * 3));  // assume never failed

  struct Param param = { {3, 4}, {p} };  
  MakeArray(&param);

  special_memory_free(p);
}

函数MakeArray可以在一个独立的模块中。我需要调用者(例如本例中的 main)为我分配 out 参数中的内存。

那么有什么方法可以提示用户对输出参数进行分配吗?

这个设计似乎对整体分配有点混乱。您传递给 MakeArray 的结构是按值传递的,因此它只是存储在堆栈上的本地副本,而不是分配的内存。虽然它碰巧有一个指针副本 c 指向分配的堆内存。

您应该遵循的一些经验法则:

  • 切勿按值传递结构。始终通过指针引用。
  • 为项目分配内存的人也是负责释放它的人。不要“外包”allocation/clean-up 给图书馆的用户,那是非常糟糕的设计。
  • 理想情况下,内存分配应该与处理结构的函数一起封装。如果您更喜欢 OO 术语,这可以称为“抽象数据类型”(ADT) 或“class”——归结为类似的东西。一个“构造”函数和一个“析构”函数。由于 C 不支持 constructors/destructors (RAII) 的自动调用,因此必须手动调用它们。但是 C 程序员习惯于期望这样,所以这不是问题。
  • 请记住,如果需要实现析构函数,则可能还需要实现某种形式的复制函数。类似于 C++ 的“三法则”(如果熟悉的话)。

实现这一点的专业方法是通过so-called 不透明类型。如何做到这一点的例子可以在这里找到:How to do private encapsulation in C?