fncs:operator new和operator new [](不是new和new []运算符)之间有什么区别吗?当然除了调用语法?我问,因为我可以使用:: operator new(sizeof(T)*numberOfObject)为我的objs分配X个字节,然后使用数组表示法访问它们,那么:: operator new []有什么大不了的.它只是语法糖吗?
#include <new>
#include <iostream>
#include <malloc.h>
using namespace std;
struct X
{
int data_;
X(int v):data_(v){}
};
int _tmain(int argc, _TCHAR* argv[])
{
unsigned no = 10;
void* vp = ::operator new(sizeof(X) * no);
cout << "Mem reserved: " << _msize(vp) << '\n';
X* xp = static_cast<X*>(vp);
for (unsigned i = 0; i < no; ++i)
{
new (xp + i) X(i);
}
for (unsigned i = 0; i < no; ++i)
{
cout << (xp[i]).data_ << '\n';
}
for (unsigned i = 0; i < no; ++i)
{
(xp + i)->~X();
}
::operator delete(vp);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这些函数(operator new等)通常不是要显式调用,而是由new/ new[]表隐式使用(对称地,operator delete/ operator delete[]functions由delete/ delete[]表隐式调用).使用new非数组类型语法的表达式将隐式调用operator new函数,而具有new[]将隐式调用的表达式operator new[].
这里重要的细节是,由new[]表达式创建的数组通常会在以后通过delete[]表达式销毁.后者需要知道要销毁的对象的数量(如果对象具有非平凡的析构函数),即该信息必须以某种方式从new[]表达式(当它已知时)传递到相应的delete[]表达式(当需要时).在典型的实现中,该信息存储在由new[]表达式分配的块内,这就是为什么在隐式调用中请求的存储器大小operator new[]通常大于元素数量和元素大小的乘积.额外空间用于存储家庭信息(元素数量,即).后来delete[]表达式将检索该家庭信息,并在通过调用实际释放内存之前使用它来调用正确数量的析构函数operator delete[].
在您的示例中,您没有使用任何这些机制.在您的示例中,您正在显式调用内存分配函数,手动执行构造并完全忽略销毁步骤(这是正常的,因为您的对象具有简单的析构函数),这意味着至少为了破坏目的,您不需要跟踪确切的数组中的元素数量.在任何情况下,您都可以在no变量中手动跟踪该数字.
但是,一般情况下是不可能的.在一般情况下,代码将使用new[]表达式和delete[]表达式和元素的数量将有从获得new[]到delete[]不知何故,这意味着它必须被存储在内部,这就是为什么有必要为数组专用的内存分配函数- operator new[].它不等同于operator new上述产品的尺寸.
void* operator new(size_t)函数和所需的行为之间没有太大区别void* operator new[](size_t),除了它们与不同的释放函数配对之外。
运营商本身有很大不同。运算符之间的差异之一是使用哪个分配函数,但最终还有许多其他差异,包括调用多少个构造函数等。但是您的示例代码没有使用运算符(好吧,它使用的是新的放置)。您可能需要更改问题标题以明确这一点。
来自部分[basic.stc.dynamic.deallocation]:
如果释放函数通过抛出异常而终止,则行为是未定义的。提供给释放函数的第一个参数的值可以是空指针值;如果是这样,并且如果释放函数是标准库中提供的函数,则调用无效。否则,标准库中提供的值应是标准库中运算符或操作符
operator delete(void*)的先前调用返回的值之一 ,并且标准库中提供的值应是先前调用的运算符返回的值之一。在标准库中调用 或。new(std::size_t)new(std::size_t, const std::nothrow_- t&)operator delete[](void*)operator new[](std::size_t)operator new[](std::size_t, const std::nothrow_t&)