如何';马洛克';和';新';工作它们有何不同(在实现方面)? p>我知道它们在语法上是如何不同的,C++使用新的,C使用的是Maloc。但从高层次的解释来看,它们是如何工作的呢
参见“新”比malloc做得更多。malloc只分配内存——它甚至不为您归零。new初始化对象、调用构造函数等。我怀疑在大多数实现中,new只不过是基本类型malloc的一个薄型包装而已。在C中: malloc按照参数中提供的大小分配内存块,并返回指向该内存的指针如何';马洛克';和';新';工作它们有何不同(在实现方面)? p>我知道它们在语法上是如何不同的,C++使用新的,C使用的是Maloc。但从高层次的解释来看,它们是如何工作的呢,c++,c,C++,C,参见“新”比malloc做得更多。malloc只分配内存——它甚至不为您归零。new初始化对象、调用构造函数等。我怀疑在大多数实现中,new只不过是基本类型malloc的一个薄型包装而已。在C中: malloc按照参数中提供的大小分配内存块,并返回指向该内存的指针 内存是在堆上声明的,因此请确保在完成后释放它。我将引导您找到以下答案:。马丁提供了一个极好的概述。快速概述它们的工作原理(无需深入探讨如何将它们作为成员函数重载): 新的表达和分配 代码包含一个提供type-id的新表达式 编译器将研
内存是在堆上声明的,因此请确保在完成后释放它。我将引导您找到以下答案:。马丁提供了一个极好的概述。快速概述它们的工作原理(无需深入探讨如何将它们作为成员函数重载): 新的表达和分配
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);
new\u handler
,并希望它能够成功。如果仍然没有足够的位置,new必须抛出std::bad_alloc
或从中派生。具有throw()
(无throw保证)的分配器,在这种情况下应返回空指针李>
new。它将no-throw
作为第二个参数。类似以下形式的新表达式将调用仅接受std::size\u t和nothrow\u t的分配函数:nothrow\t
new (std::nothrow) TypeId;
。它将void*指针作为第一个参数,并返回该参数,而不是返回新分配的内存地址。它用于在给定地址创建对象。标准容器使用它来预先分配空间,但只在需要时创建对象,以后再创建新位置
new (a, b, c) TypeId;
然后调用接受这些参数的运算符delete。仅当由于对象的构造函数确实抛出而完成删除时,才会调用该运算符delete version。如果您自己调用delete,那么编译器将使用普通运算符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 (possible_arguments) TypeId[N];
编译器正在使用运算符new[]
函数,而不是普通的运算符new
。可以向运算符传递第一个参数,该参数不完全是sizeof(TypeId)*N
:编译器可以添加一些空间来存储创建的对象数(必须能够调用析构函数)。标准是这样说的:
导致呼叫操作员new T[5]
,以及new[](sizeof(T)*5+x)
导致呼叫操作员new(2,f)T[5]
new[](sizeof(T)*5+y,2,f)
malloc
不同的是新的功能如下:
- 它通过调用
操作符new
在分配的内存中构造一个值。可以通过重载此运算符来调整此行为,可以针对所有类型,也可以仅针对您的类
- 如果无法分配内存,它将调用处理程序函数。如果您事先注册了这样一个处理函数,那么您就有机会动态地释放所需的内存
- 如果这没有帮助(例如,因为您没有注册任何函数),它将抛出异常
总之,new
是高度可定制的,除了内存分配之外,它还进行初始化工作。这是两大区别。尽管malloc
/free
和new
/delete
有不同的行为,但它们都在低级别上做相同的事情:管理动态分配的内存。我想这就是你真正想问的。在我的系统中,new
实际上在内部调用malloc
来执行其分配,所以我将只讨论malloc
malloc
和free
的实际实现可能会有很大不同,因为有很多方法可以实现内存分配。有些方法可以获得更好的性能,有些方法可以减少内存浪费,有些方法更适合调试。垃圾收集语言也可能有完全不同的分配方式,但您的问题是关于C/C++
通常,块是从堆中分配的,堆是程序地址空间中的一个大内存区域。库为您管理堆,通常使用系统调用,如sbrk
或mmap
。从堆中分配块的一种方法是维护空闲块和已分配块的列表,其中存储块大小和位置。最初,列表可能包含整个堆的一个大块。当请求一个新块时,分配器将从列表中选择一个空闲块。如果块太大,可以将其拆分为两个块(一个是请求的大小,另一个是剩余的任何大小)。释放分配的块时,它可以与相邻的空闲块合并,因为有一个大的空闲块比几个小的空闲块更有用。实际的块列表可以是sto
new (possible_arguments) TypeId[N];