我正在实现一个C API,它公开从systemd服务收集的一些数据。API的头包含两个结构:
typedef struct Info {
int latest;
int prev;
int cur;
} Info;
typedef struct InfoArray {
Info *info;
} InfoArray;
这个C头的实现是用C++编写的,我计划提供一个create(size_t size) function
,让用户创建一个具有用户输入大小的数组的新结构。然后,可以通过引用将返回的数组传递给另一个函数,以用数据填充数组,直到数组达到用户定义的大小。
我将如何实现这一点?
编辑:我正在寻找一种返回大小为n的分配数组的方法,但我尝试了以下方法:
InfoArray *create(size_t size) {
InfoArray *array = (InfoArray *)malloc(size * sizeof(Info));
return array;
}
哪个应该返回分配的数组,但当试图通过调用delete info
在客户端删除数组时,我得到一个错误,我无法释放该句柄,那么我如何让API的使用者管理内存的删除?
由于实现是在.cpp文件(C++(中编写的,我认为必须有一种方法可以通过使用新运算符来返回它,但我未能像这样实现它。
使用malloc()
时,要清除对象,必须使用free()
。这是做事的C方式。
使用C++时,请改用new
和delete
,如下所示:InfoArray *array = new InfoArray[size];
然而,当使用C++时,我会敦促您只转储InfoArray,然后使用std::vector<Info>
之类的东西。
编辑:
这个C头的实现是用C++编写的
这没有意义。它要么是C单元,要么是C++单元。这是两种不同的语言,你只能选择一种。相似的语法和良好的界面性并不能改变这一点。
我看到了"我正在实现一个C API";,所以接口是C,我理解
我明白了"这个C头的实现是用C++"编写的;因此,根据您的设计,接口后面的代码是C++
我明白了"尝试通过调用CCD_ 9"来删除客户端上的阵列;,所以调用代码也是C++。
严格地说,可以想象使用C++中的C接口,甚至用C接口在C++中实现它。我只是真的希望这不是OP想要的
但是,无论C接口产生什么,delete
都不会接受,使用C接口的C++代码必须接受它是C接口,并在mallocated指针上使用free()
这就是我建议重新设计界面的原因。要么放弃两个C++之间的C接口,转而使用C++接口。或者使用C接口,放弃使用delete
的想法。
如何让API的使用者管理内存的删除?
释放问题是C习惯用法要求调用方提供缓冲区的原因之一:
int fillInfo(InfoArray *array, size_t arraySize) {
memcopy...
return countCopied;
}
在这种方法中,API从不分配任何东西,它只将数据复制到提供的缓冲区中。就像strcpy
一样。这种方法的巨大好处是,客户可以使用他们目前认为合适的任何分配方法。
如果你真的必须返回一个新的缓冲区,那么提供一对方法:
InfoArray *create(size_t size);
void release(array* InfoArray);
这样,客户端既不知道也不关心对象是如何分配和释放的。当您想限制客户端如何分配内存时,这很有用,但请注意,客户端仍然负责内存管理,它仅限于一个选项。它仍然不能保证客户端不会以未经批准的方式使用分配的内存。
在客户端和库之间的分界线两侧保留分配和释放是在自讨苦吃。您向客户端作者隐瞒了内存是如何分配的,但您要求他们使用正确的释放方法。这正是罪魁祸首。