你可以混合使用C++的
std::malloc
和C的
free
。
在C++中,
std::malloc
的定义在
<cstdlib>
中,据说与C中的
<stdlib.h>
具有相同的内容和意义(有一些变化,比如命名空间)。此外,
[c.malloc]中提到:
void* aligned_alloc(size_t alignment, size_t size);
void* calloc(size_t nmemb, size_t size);
void* malloc(size_t size);
void* realloc(void* ptr, size_t size);
Effects: These functions have the semantics specified in the C standard library.
这意味着你可以在C++中使用
std::malloc
分配一些内存,并将其传递给调用
free
的某个C函数。
注意:混合使用不同的标准库或混合使用相同标准库的不同版本(调试/发布)可能仍然存在问题,但这适用于所有语言特性。
C++标准库不使用std::malloc
话虽如此,像您所建议的那样,对于由std::vector分配的内存使用free是不安全的。
所有进行内存分配的容器默认使用std::allocator,它使用operator new。
即使底层操作系统函数用于获取和释放内存相同,混合使用new和free也会导致未定义的行为。
如何在C中使用std::vector
struct vector {
alignas(void*) unsigned char data[3 * sizeof(void*)];
};
void vector_init(struct vector*);
void vector_destroy(struct vector*);
void vector_push(struct vector*, int element);
int main() {
vector v;
vector_init(&v);
vector_push(&v, 42);
vector_destroy(&v);
}
到目前为止,我们基本上只是定义了一个
struct vector
来包含一些字节的数量,以及三个不透明的函数。所有的代码都是C23兼容的,我们可以在C++中实现实际的功能。
static_assert(alignof(vector::data) >= alignof(std::vector));
static_assert(sizeof(vector::data) >= sizeof(std::vector));
extern "C" void vector_init(vector* v) {
std::construct_at(reinterpret_cast<std::vector<int>*>(v->data));
}
extern "C" void vector_destroy(vector* v) {
std::destroy_at(reinterpret_cast<std::vector<int>*>(v->data));
}
extern "C" void vector_push(vector* v, int element) {
auto* vec = std::launder(reinterpret_cast<std::vector<int>*>(v->data));
vec->push_back(element);
}
C++端使用std::construct_at(或在C++20之前,可以使用placement new)。我们在vector::data的原始字节中创建一个std::vector。
请注意,在此代码中我们没有调用new、delete、malloc或free。
std::vector仍然负责所有的内存管理。
malloc
/free
相同的机制完成的。然而,如果你使用C++中的malloc
创建了向量的副本,你可以在C中使用free
来释放它。 - undefined