c – ‘malloc’和’new’如何工作?它们有何不同(实施明智)?

前端之家收集整理的这篇文章主要介绍了c – ‘malloc’和’new’如何工作?它们有何不同(实施明智)?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我知道它们在语法上是如何不同的,并且C使用new,而C使用malloc.但他们是如何运作的,在一个高级别的解释中呢?

What is the difference between new/delete and malloc/free?

解决方法

我只想指导你这个答案: What is the difference between new/delete and malloc/free?.马丁提供了很好的概述.快速了解它们的工作原理(无需考虑如何将它们作为成员函数重载):

新表达和分配

>代码包含一个提供type-id的new-expression.
>编译器将查看类型是否使用分配函数重载operator new.
>如果它发现运算符新分配函数的重载,则使用赋予new和sizeof(TypeId)作为其第一个参数的参数调用函数

样品:

new (a,b,c) TypeId;

// the function called by the compiler has to have the following signature:
operator new(std::size_t size,TypeOfA a,TypeOfB b,TypeOf C c);

>如果operator new无法分配存储空间,它可以调用new_handler,并希望它能够生成.如果仍然没有足够的位置,new必须抛出std :: bad_alloc或从中派生.一个具有throw()(无抛出保证)的分配器,在这种情况下它应该返回一个空指针.
> C运行时环境将创建由分配函数返回的内存中由type-id指定的类型的对象.

给出了一些特殊名称的特殊分配函数

>不要扔新的.这需要一个nothrow_t作为第二个参数.如下所示的表单的新表达式将调用仅使用std :: size_t和nothrow_t的分配函数

例:

new (std::nothrow) TypeId;

>安置新.这将void *指针作为第一个参数,而不是返回新分配的内存地址,它返回该参数.它用于在给定地址创建对象.标准容器使用它来预分配空间,但稍后只在需要时创建对象.

码:

// the following function is defined implicitly in the standard library
void * operator(std::size_t size,void * ptr) throw() {
    return ptr;
}

如果分配函数返回存储,并且运行时创建的对象的构造函数抛出,则会自动调用operator delete.如果使用了一种新的形式,它需要额外的参数,比如

new (a,c) TypeId;

然后调用那些参数的运算符delete.只有在删除完成时才调用该运算符删除版本,因为对象的构造函数确实抛出了.如果你自己调用delete,那么编译器将使用普通的operator delete函数,只取一个void *指针:

int * a = new int;
=> void * operator new(std::size_t size) throw(std::bad_alloc);
delete a;
=> void operator delete(void * ptr) throw();

TypeWhosCtorThrows * a = new ("argument") TypeWhosCtorThrows;
=> void * operator new(std::size_t size,char const* arg1) throw(std::bad_alloc);
=> void operator delete(void * ptr,char const* arg1) throw();

TypeWhosCtorDoesntThrow * a = new ("argument") TypeWhosCtorDoesntThrow;
=> void * operator new(std::size_t size,char const* arg1) throw(std::bad_alloc);
delete a;
=> void operator delete(void * ptr) throw();

new-expression和数组

如果你这样做

new (possible_arguments) TypeId[N];

编译器使用operator new []函数而不是plain operator new.操作符可以传递第一个不完全是sizeof的参数(TypeId)* N:编译器可以添加一些空间来存储创建的对象数(为了能够调用析构函数而需要).标准就是这样说的:

> new T [5]导致调用operator new [](sizeof(T)* 5 x),和> new(2,f)T [5]导致运算符new []的调用(sizeof(T)* 5 y,2,f).

猜你在找的C&C++相关文章