用于堆上内存分配的新运算符

时间:2011-02-09 06:02:09

标签: c++ memory-management new-operator operator-keyword dynamic-memory-allocation

我正在看新操作员的签名。这是:

void* operator new (std::size_t size) throw (std::bad_alloc);

但是当我们使用这个运算符时,我们从不使用强制转换。即

 int *arr = new int;

那么,在这种情况下,C ++如何将void*类型的指针转​​换为int*。因为,即使malloc返回void*,我们也需要明确使用强制转换。

2 个答案:

答案 0 :(得分:41)

operator newnew运算符之间的C ++存在非常细微的差别。 (再看一遍......排序很重要!)

函数operator new是C malloc函数的C ++模拟。它是一个原始内存分配器,其职责仅仅是生成一块内存块来构造对象。它不会调用任何构造函数,因为这不是它的工作。通常,您不会在C ++代码中看到operator new直接使用;它看起来有点奇怪。例如:

void* memory = operator new(137); // Allocate at least 137 bytes

new运算符是一个关键字,负责为对象分配内存并调用其构造函数。这是C ++代码中最常见的。当你写

int* myInt = new int;

您正在使用new运算符来分配新整数。在内部,new运算符的工作方式大致如下:

  1. 使用operator new
  2. 分配内存以保存请求的对象
  3. 调用对象构造函数(如果有)。如果这会引发异常,请使用operator delete释放上述内存,然后传播异常。
  4. 返回指向新构造对象的指针。
  5. 由于new运算符和operator new是分开的,因此可以使用new关键字构造对象而无需实际分配任何内存。例如,着名的 placement new 允许您在用户提供的内存中的任意内存地址上构建对象。例如:

    T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer
    new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.'
    

    通过定义自定义new功能来重载operator new运算符,可以通过这种方式使用new;您可以指定分配的方式,C ++编译器会将其连接到new运算符。

    如果您感到好奇,delete关键字的工作方式相同。有一个名为operator delete的释放函数负责处理内存,还有一个delete运算符负责调用对象析构函数和释放内存。但是,operator newoperator delete可以在这些上下文之外使用,例如代替C mallocfree

答案 1 :(得分:5)

您将new表达式与operator new()函数混淆了。编译前者时,编译器会生成对operator new()函数的调用,并传递足够大小以保存new表达式中提到的类型,然后返回该类型的指针。