C语言中的free和C ++中的delete之间的区别? [英] The differences between free in C and delete in C++?
问题描述
我知道 C 中的空闲操作是告诉编译器该特定的内存块是免费的,供编译器用于进一步分配,但不释放内存。
I know the free operation in C is to tell the compiler this particular memory block is free for compiler to use for further allocation, but the memory is not released.
在C ++中删除怎么办?
What about the delete in C++? the same as free?
推荐答案
在其中有两个删除
概念C ++:一个是 operator ,声明为 :: operator delete(void *)
,它基本上只释放内存,通常不释放大多数程序员都想到过。另一个是 delete表达式, delete p;
,其中 p
是 T *
。该表达式调用 p
指向的对象的析构函数(然后释放内存),这是C ++的重要语言功能,在C中没有类似物。
There are two notions of delete
in C++: One is the operator, declared as ::operator delete(void*)
, which basically only frees up the memory and isn't usually thought about by most programmers. The other is the delete expression, delete p;
, where p
is a T*
. The expression invokes the destructor of the object pointed to by p
(and then frees the memory), which is a crucial language feature of C++ that has no analogue in C.
根据经验,将新
表达式与删除
表达式以及 malloc()
函数调用和 free()
函数调用:
As a rule of thumb, you pair new
expressions with delete
expressions, and malloc()
function calls with free()
function calls:
T * p = new T; // constructor called!
delete p; // destructor called!
void * x = malloc(5); // just raw memory
free(x); // freed
高级部分(不响应OP的问题)
C ++中的动态对象生存期遵循以下一般模式:分配,构造,销毁,释放。标准的 new
表达式执行分配和构造,而标准的 delete
表达式执行销毁和释放。
Dynamic object lifetime in C++ follows this general pattern: Allocate, construct, destroy, deallocate. The standard new
expression performs allocation and construction, while the standard delete
expression performs destruction and deallocation.
您可以手动写出该过程:
You could write out the process manually:
T * p = (T*)::operator new(sizeof(T)); // allocate raw memory
p = new (p) T; // call the constructor ("placement new")
/*...*/
p->~T(); // destroy the object
::operator delete(p); // deallocate the memory
实际上,如果您确实想实现Baby's First C ++,则可以定义操作符,就像 malloc
/ 免费
:
In fact, if you really wanted to implement Baby's First C++, you could define the operators as just as malloc
/free
:
void * operator new(size_t n) { return malloc(n); }
void operator delete(void * p) { free(p); }
真正的C ++神奇之处在于 new
和 delete
表达式:标准的 new
表达式将调用构造函数(分配后,code> new 表达式是在C ++中调用构造器的唯一方法!),而标准delete表达式在释放之前调用析构函数。
The real C++ magic happens by virtue of the new
and delete
expressions: The standard new
expression invokes the constructor (a new
expression is the only way to call a constructor in C++!) after allocation, while the standard delete expression invokes the destructor before deallocation.
为什么要使用标准表达式?好了,您还可以定义并重载许多其他版本的 new
和 delete
运算符。但是,存在一个重要的不对称性:虽然您可以在自定义的 new
表达式中使用自定义的 new
运算符(通常称为 placement new),没有等效的 placement-delete表达式。因此,无论何时使用自定义 new
表达式,都必须在调用匹配的自定义删除 operator
Why "standard expression"? Well, you can also define and overload many other versions of new
and delete
operators. However, there is an important asymmetry: While you can use a custom new
operator in a custom new
expression (generally dubbed "placement new"), there is no equivalent "placement-delete" expression. So whenever you use a custom new
expression, you have to manually invoke the destructor before calling the matching custom delete operator:
T * p = new (A, B, C) T; // some custom new expression
// Entirely equivalent version:
T * p = (T*) ::operator new(sizeof(T), A, B, C); // this is your custom overload
T * p = new (p) T; // std. placement-new expression calls constructor
/* ---- later ---- */
p->~T(); // Must destroy manually!
::operator delete(p, A, B, C); // your matching custom overload
请注意,不存在自定义删除表达式删除(A,B,C)p'
!
Note that there does not exist a custom delete expression delete (A,B,C) p'
!
为了完整起见,请使用标准位置新运算符,标准要求其唯一目的是调用构造函数,
For completeness, the standard placement new operator, whose only purpose is to call a constructor, is mandated by the standard to take the following form:
void * operator new(size_t, void * p) { return p; }
它与 delete
operator相匹配也被强制使用,名称不能执行任何操作:
It's matching delete
operator is also mandated, name to do nothing:
void operator delete(void * p, void *) { }
您可以在上面的一般示例中看到为什么这样做是必要的。
You can see in the above general example why this is necessary.
始终要成对重载 new
和 delete
的自定义版本,这一点很重要!原因是,如果对象构造因构造函数内部的异常而失败,则通过调用 delete
运算符(与有问题的 new
表达式。
It is important always to overload custom versions of new
and delete
in pairs! The reason is that if the object construction fails with an exception inside the constructor, then the memory is released by a call to the delete
operator that matches the offending new
expression.
第二次更新: -安全,我们必须考虑 T
的构造函数可能会抛出:
Second update: To be exception-safe, we have to consider that the constructor of T
might throw:
版本1:
try {
T * p = new (A, B, C) T;
/* ... */
p->~T();
::operator delete(p, A, B, C); // automatically invoked if T::T() throws!
}
catch(...) { }
版本2:
void * addr = ::operator new(sizeof(T), A, B, C);
try {
T * p = new (addr) T; // might throw
/* ... */
p->~T();
// ::operator delete(p, addr); // ditto as in (1), but does nothing
}
catch(...) { }
::operator delete(addr, A, B, C);
这篇关于C语言中的free和C ++中的delete之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!