什么相当于C中的C++新/删除?

htt*_*ret 27 c c++ new-operator delete-operator

什么相当于C中的C++新/删除?

或者它在C/C++中是一样的?

ken*_*ytm 46

C中没有new/ delete表达

如果忽略构造函数/析构函数并键入安全性,则最接近的等价函数mallocfree函数.

#include <stdlib.h>

int* p = malloc(sizeof(*p));   // int* p = new int;
...
free(p);                       // delete p;

int* a = malloc(12*sizeof(*a));  // int* a = new int[12];
...
free(a);                         // delete[] a;
Run Code Online (Sandbox Code Playgroud)

  • @stakx`sizeof`运算符是从**type**到`size_t`的映射.其操作数的**值**根本没有意义.例如,在`sizeof(1 + 2)`中,绝对不需要计算结果`3`.`sizeof`运算符只是看到一个类型为`int + int`的表达式,并推断结果也是一个`int`.然后它将`int`映射到4(或2或8,具体取决于平台).`sizeof(*p)`也是一样的.类型系统知道,在类型级别上,解引用`int*`会产生一个`int`.`sizeof`根本不对`*p`的值感兴趣,只有类型很重要. (10认同)
  • @stakx出于完全相同的原因,`sizeof(1/0)`不会因算术异常而崩溃,而是产生`sizeof(int)`,因为`1`的类型是`int`,`0`是类型为`int`,并且两个`int`s的除法也在类型级别上产生一个`int`.在编译时和运行时都不会执行除法! (10认同)
  • @stakx:`sizeof`运算符在编译时计算.没有解除引用.`sizeof(*p)`比`sizeof(int)`更受欢迎,因为如果你将`p`的类型改为`double`,编译器就无法警告你大小不匹配. (7认同)
  • *@ KennyTM:*`sizeof(*p)`实际上取消引用`p`,还是完全等同于写`sizeof(int)`?似乎在前一种情况下,这个表达式可能会导致分段错误(因为此时尚未分配"p").在后一种情况下,我可能仍然更喜欢编写`sizeof(int)`,因为误解这个语句的作用的可能性较小. (2认同)
  • 感谢你们两位回复.我以为我会问,因为我之前没有看过`sizeof`的用法.不过要知道好事! (2认同)

fre*_*low 7

请注意,构造函数可能会在C++中抛出异常.player* p = new player();在C中相当于这样的东西.

struct player *p = malloc(sizeof *p);
if (!p) handle_out_of_memory();
int err = construct_player(p);
if (err)
{
    free(p);
    handle_constructor_error();
}
Run Code Online (Sandbox Code Playgroud)

相当于delete p更简单,因为析构函数永远不应该"抛出".

destruct(p);
free(p);
Run Code Online (Sandbox Code Playgroud)


Pet*_*ham 6

在C++中使用newdelete结合了两个职责 - 分配/释放动态内存,以及初始化/释放对象.

正如所有其他答案所说,分配和释放动态内存的最常见方式是调用mallocfree.您还可以使用特定于操作系统的函数来获取大量内存并在其中分配您的对象,但这种情况很少见 - 只有当您具有malloc不满足的相当具体的要求时.

在C中,大多数API将提供对那些履行的其他角色的功能newdelete.

例如,文件api使用一对打开和关闭函数:

// C++
fstream* fp = new fstream("c:\\test.txt", "r");
delete fp;

// C
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp);
Run Code Online (Sandbox Code Playgroud)

这可能是因为fopen使用malloc分配的存储的FILE结构体,或者它可以静态分配的表为文件指针的工艺开始时的最大数目.关键是,API不要求客户端使用mallocfree.

其他API提供的功能只是执行初始化和释放合同的一部分 - 相当于构造函数和析构函数,它允许客户端代码使用自动,静态或动态存储.一个例子是pthreads API:

pthread_t thread;

pthread_create( &thread, NULL, thread_function, (void*) param); 
Run Code Online (Sandbox Code Playgroud)

这允许客户端更灵活,但增加了库和客户端之间的耦合 - 客户端需要知道pthread_t类型的大小,而如果库处理分配和初始化,则客户端不需要知道类型的大小,因此实现可以改变而不改变客户端.既不像C++那样在客户端和实现之间引入尽可能多的耦合.(将C++视为使用vtables而不是OO语言的模板元编程语言通常会更好)