在混合的 C 和 C++ 代码中使用 operator new
Using operator new in mixed c and c++ code
考虑一个混合了 C 和 C++ 代码的程序。 C++ 部分包含一个 class,它动态地分配一个 C 风格的 typedef struct
。最小示例:
obj.h(C 代码)
typedef struct _Ctype {
int i;
} Ctype;
class.hpp(C++代码)
struct A {
struct _Ctype *x;
A(int i);
~A();
};
class.cpp(C++代码)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = new struct _Ctype;
x->i = i;
}
A::~A()
{
delete(x);
}
main.cpp(C++代码,主程序)
#include "class.hpp"
int main()
{
A a(3);
return 0;
}
(这个设计的原理来源于)
使用 new
表达式分配 C 风格的类型 struct _Ctype
是否安全(即没有 UB),如上面的代码所示,或者最好使用 C-样式 malloc
/free
?
class.cpp(C++代码,备选)
#include <cstdlib>
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = (struct _Ctype *)malloc(sizeof(struct _Ctype));
x->i = i;
}
A::~A()
{
free(x);
}
加法
在下面的一些评论后澄清问题:在上面的最小示例中,所有代码都是用 C++ 编译器编译的。然而,人们可以考虑将 C++ 代码与 C 库结合使用。然后可以将问题重新表述如下:
- 如果我通过 C++ 代码为 C 风格
typedef struct
分配内存,C 库可以 安全地 使用分配的变量吗?如果是这样,上面给出的替代方案是否安全?
请注意,也可以考虑通过 C 函数为 Ctype
分配内存,以便 C++ 代码仅管理指向它的指针,例如:
obj.h(C 代码)
typedef struct _Ctype {
int i;
} Ctype;
Ctype *allocate_Ctype();
void deallocate_Ctype(Ctype* p);
obj.C(C 代码)
#include <stdlib.h>
#include "obj.h"
Ctype *allocate_Ctype()
{
return (Ctype *)malloc(sizeof(Ctype));
}
void deallocate_Ctype(Ctype *p)
{
free(p);
}
class.cpp(C++代码)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = allocate_Ctype();
x->i = i;
}
A::~A()
{
deallocate_Ctype(x);
}
(注:当然classA的拷贝构造函数和运算符赋值需要正确定义,代码说明问题)
只要释放只在您的控制下发生并使用 delete
表达式,就完全没有问题。与结构交互的 C 代码不关心它是如何分配的。
旁注:名称 _Ctype
在 C++ 中是不合法的,因为它以下划线开头,后跟大写字母。此类名称(以及包含双下划线的名称)为编译器和标准库保留。
考虑一个混合了 C 和 C++ 代码的程序。 C++ 部分包含一个 class,它动态地分配一个 C 风格的 typedef struct
。最小示例:
obj.h(C 代码)
typedef struct _Ctype {
int i;
} Ctype;
class.hpp(C++代码)
struct A {
struct _Ctype *x;
A(int i);
~A();
};
class.cpp(C++代码)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = new struct _Ctype;
x->i = i;
}
A::~A()
{
delete(x);
}
main.cpp(C++代码,主程序)
#include "class.hpp"
int main()
{
A a(3);
return 0;
}
(这个设计的原理来源于
使用 new
表达式分配 C 风格的类型 struct _Ctype
是否安全(即没有 UB),如上面的代码所示,或者最好使用 C-样式 malloc
/free
?
class.cpp(C++代码,备选)
#include <cstdlib>
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = (struct _Ctype *)malloc(sizeof(struct _Ctype));
x->i = i;
}
A::~A()
{
free(x);
}
加法
在下面的一些评论后澄清问题:在上面的最小示例中,所有代码都是用 C++ 编译器编译的。然而,人们可以考虑将 C++ 代码与 C 库结合使用。然后可以将问题重新表述如下:
- 如果我通过 C++ 代码为 C 风格
typedef struct
分配内存,C 库可以 安全地 使用分配的变量吗?如果是这样,上面给出的替代方案是否安全?
请注意,也可以考虑通过 C 函数为 Ctype
分配内存,以便 C++ 代码仅管理指向它的指针,例如:
obj.h(C 代码)
typedef struct _Ctype {
int i;
} Ctype;
Ctype *allocate_Ctype();
void deallocate_Ctype(Ctype* p);
obj.C(C 代码)
#include <stdlib.h>
#include "obj.h"
Ctype *allocate_Ctype()
{
return (Ctype *)malloc(sizeof(Ctype));
}
void deallocate_Ctype(Ctype *p)
{
free(p);
}
class.cpp(C++代码)
#include "class.hpp"
extern "C" {
#include "obj.h"
}
A::A(int i)
{
x = allocate_Ctype();
x->i = i;
}
A::~A()
{
deallocate_Ctype(x);
}
(注:当然classA的拷贝构造函数和运算符赋值需要正确定义,代码说明问题)
只要释放只在您的控制下发生并使用 delete
表达式,就完全没有问题。与结构交互的 C 代码不关心它是如何分配的。
旁注:名称 _Ctype
在 C++ 中是不合法的,因为它以下划线开头,后跟大写字母。此类名称(以及包含双下划线的名称)为编译器和标准库保留。