如何';马洛克';和';新';工作它们有何不同(在实现方面)? p>我知道它们在语法上是如何不同的,C++使用新的,C使用的是Maloc。但从高层次的解释来看,它们是如何工作的呢

如何';马洛克';和';新';工作它们有何不同(在实现方面)? p>我知道它们在语法上是如何不同的,C++使用新的,C使用的是Maloc。但从高层次的解释来看,它们是如何工作的呢,c++,c,C++,C,参见“新”比malloc做得更多。malloc只分配内存——它甚至不为您归零。new初始化对象、调用构造函数等。我怀疑在大多数实现中,new只不过是基本类型malloc的一个薄型包装而已。在C中: malloc按照参数中提供的大小分配内存块,并返回指向该内存的指针 内存是在堆上声明的,因此请确保在完成后释放它。我将引导您找到以下答案:。马丁提供了一个极好的概述。快速概述它们的工作原理(无需深入探讨如何将它们作为成员函数重载): 新的表达和分配 代码包含一个提供type-id的新表达式 编译器将研

参见

“新”比malloc做得更多。malloc只分配内存——它甚至不为您归零。new初始化对象、调用构造函数等。我怀疑在大多数实现中,new只不过是基本类型malloc的一个薄型包装而已。

在C中: malloc按照参数中提供的大小分配内存块,并返回指向该内存的指针


内存是在堆上声明的,因此请确保在完成后释放它。

我将引导您找到以下答案:。马丁提供了一个极好的概述。快速概述它们的工作原理(无需深入探讨如何将它们作为成员函数重载):

新的表达和分配
  • 代码包含一个提供type-id的新表达式
  • 编译器将研究该类型是否使用分配函数重载new运算符
  • 如果发现运算符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);
    
  • 如果操作员new未能分配存储,它可以调用
    new\u handler
    ,并希望它能够成功。如果仍然没有足够的位置,new必须抛出
    std::bad_alloc
    或从中派生。具有
    throw()
    (无throw保证)的分配器,在这种情况下应返回空指针
  • C++运行时环境将创建由分配函数返回的内存中的type ID所提供的类型的对象。<李> 有一些特殊的分配函数具有特殊的名称:

    • no-throw
      new。它将
      nothrow\t
      作为第二个参数。类似以下形式的新表达式将调用仅接受std::size\u t和nothrow\u t的分配函数:
    例如:

    new (std::nothrow) TypeId;
    
    • 新位置
      。它将void*指针作为第一个参数,并返回该参数,而不是返回新分配的内存地址。它用于在给定地址创建对象。标准容器使用它来预先分配空间,但只在需要时创建对象,以后再创建
    代码:

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

    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];