C API 设计:谁应该分配内存?

57

在 C API 中,适当/首选的内存分配方式是什么?

一开始我可以看到两种选项:

1)让调用者处理所有(外部)内存管理:

myStruct *s = malloc(sizeof(s));
myStruct_init(s);

myStruct_foo(s);

myStruct_destroy(s);
free(s);

_init_destroy函数是必需的,因为内部可能会分配更多的内存,而这些内存必须在某处处理。

这种方法的缺点是代码会变得更长,但在某些情况下可以省略malloc(例如,可以传递栈分配的结构体):

int bar() {
    myStruct s;
    myStruct_init(&s);

    myStruct_foo(&s);

    myStruct_destroy(&s);
}

另外,调用者需要知道结构体的大小。

2) 在_init中隐藏malloc,并在_destroy中隐藏free

优点:代码更短,因为这些函数总是会被调用。结构体完全不透明。

缺点:无法传递以其他方式分配的结构体。

myStruct *s = myStruct_init();

myStruct_foo(s);

myStruct_destroy(foo);

目前我倾向于第一种情况;但是,我对C API设计不了解。


3
顺便说一下,我觉得这会是一个很好的面试问题,可以比较并对比这两种设计。 - frankc
3
这是Armin Ronacher写的一篇关于如何使结构体不透明但仍允许自定义分配的文章:http://lucumr.pocoo.org/2013/8/18/beautiful-native-libraries/。 - Sam Hartsfield
11个回答

0

看看你的第二种方法说

myStruct *s = myStruct_init();

myStruct_foo(s);

myStruct_destroy(s);

现在看看如果myStruct_init()因为各种原因需要返回一些错误代码,那么我们就这样做。
myStruct *s;
int ret = myStruct_init(&s);  // int myStruct_init(myStruct **s);

myStruct_foo(s);

myStruct_destroy(s);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接