【发布时间】:2022-10-13 16:57:31
【问题描述】:
我正在为 C 实现一个 API。代码库本身纯粹是用 C++ 编写的,我只打算为使用 C 的任何消费者提供所述接口。接口定义在。H文件,而实现本身是用 C++ 编写的。我多次阅读过,使用 C++ 实现 C 接口并不是最好的主意,但在我的情况下效果很好。
无论如何,标头定义看起来类似于:
extern 'C' {
typedef struct Person {
const char *name;
uint32_t age;
uint32_t post_code;
} Person;
typedef struct PersonArray {
Person *person;
size_t size;
} PersonArray;
PersonArray *create(size_t size);
void destroy(PersonArray *array);
int fillArray(PersonArray *array);
}
我希望消费者检索 PersonArray 的句柄,其中包含一个 Person 结构数组,分配的大小传递给create() function。
由于实现是在 C++ 中,我尝试通过以下方式分配内存:
static inline Person convert(const otherNamespace::Person &o_person) {
Person p{};
p.name = o_person.name;
p.age = o_person.age;
p.post_code = o_person.post_code;
return p;
}
PersonArray *create(size_t size) {
if (size <= 0) {
return nullptr;
}
PersonArray *array = new PersonArray();
array->size = size;
array->person = new Person[size]
return array;
}
void destory(PersonArray *array) {
delete array;
}
int fillArray(PersonArray *array) {
if (array == nullptr) {
return 1;
}
auto data = // retrieve std::vector<otherNamespace::Person> via RPC
for (auto i{0U}; i < array->size; i++) {
array->person[i] = convert(data.at(i);
}
return 0;
}
不幸的是,这种方法似乎不能正常工作,因为当使用像 valgrind 这样的 memchecker 时,堆上仍然有未正确释放的块。我想new Person[size] 行没有被释放。
知道如何解决此内存泄漏吗?或者是否有另一种更适合这个特定用例的设计?如果可能的话,我真的很想用 C++ 来实现。
【问题讨论】:
-
我数了两个
new和一个delete。那么为什么没有delete array->person? -
有没有办法同时删除
PersonArray并释放结构的成员?我真的必须先delete array->person然后再拨打delete array吗? @KamilCuk -
此外,代码
*array->person[i] = // fill with data看起来很奇怪。你在做浅拷贝吗?请提供minimal reproducible example。 -
Isn't there a way to delete PersonArray and deallocate the members of the struct at the same time?不,每个程序都有一个堆,一切都是按顺序发生的。Do I really have to first delete array->person and then call delete array afterwards?是的。 (为什么会让人困惑?你“真的”做了两个new,所以现在你真的必须做两个delete) -
@GM在我的初始帖子中添加了一个编辑,显示了如何复制数据。不确定这是否是最好的方法,总是愿意接受更好的建议。还在学习 :)
标签: c++ c memory-management c-api