一、 new/new[]的使用
new的四种使用方法:
1. MyClass * p1 = new MyClass;
1. MyClass * p1 = new MyClass;
分配一个对象,内存若不够则发出bad_alloc异常。 如果异常没有被catch捕获, 则程序中止。
内部原理,new分为两个执行步骤:1. 调用 void* operator new (std::size_t size);2. 调用对象的构造函数。
使用举例1:
try
{
int* myarray= new int[10000];
}
catch (std::bad_alloc& ba)
{
std::cerr << "bad_alloc caught: " << ba.what() << '\n';
}
使用举例2:
int* myarray= new int[10000];
//说明:在内存不足的时候,new会发异常。由于异常没有被catch捕获,则将会中断程序的执行。由于内存不够引起的错误将会发出异常,因此此处不需对myarray进行判0比较。
2. MyClass * p2 =
new (std::nothrow) MyClass;
分配一个对象,内存不够则返回空指针。
内部原理,分两个步骤:
1. 调用 void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
1. 调用 void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
2. 调用对象的构造函数。
使用举例:
char* p = new (std::nothrow) char [1048576];
if (p==0) std::cout << "Failed!\n";
3.
new (p2) MyClass;
不分配空间,调用p2的构造函数,MyClass 表示p2指针所指类型,并返回p2指针。
不分配空间,调用p2的构造函数,MyClass 表示p2指针所指类型,并返回p2指针。
内部原理, 分为两个步骤:
1. 调用 void* operator new (std::size_t size, void* ptr) noexcept;
1. 调用 void* operator new (std::size_t size, void* ptr) noexcept;
2. 调用指针对应的构造函数。
4. MyClass * p3 = (MyClass*) ::
operator
new (
sizeof(MyClass));
仅分配空间,不调用构造函数。
new[]用于数组的动态分配,类似的四种使用方法为:
1. MyClass * p1 =
new MyClass[5];
2. MyClass * p2 =
new (std::nothrow) MyClass[5];
3. MyClass * p3 =
static_cast<MyClass*> (::
operator
new (
sizeof(MyClass[5])));
4.
new (p3) MyClass[5];
参考文献:
二、
c++ 内存分配 new 和 allocator
关于内存的分配,有两种方式:采用操作符new 或者使用类 allocator。
使用方法
两者典型的使用方法如下(其中typename泛指类型名字;typepoint泛指指向该类型的指针):
typepoint = new typename;
如 string *p = new string;
std::allocator<typename> alloc;
typepoint = alloc.allocator(num);
如 std::allocator<string> alloc;
string *p = alloc.allocator(1);
不同
两者最大的不同是,对于new而言,在分配一块内存空间的时候,还会调用构造函数,如上例子,将会调用string的构造函数;但是,对于allocator而言,仅仅负责分配一块空间,不会调用构造函数。
适用范围
对于一般应用的时候,通常采用new。
在STL中,而是采用allocator来分配内存。
原理分析
已知:
string *sp = new string("a value");
对于new, 基于上面例子此时实际进行了三步操作:1. 调用库函数 operator new (或者 operator new[])分配原始,没有类型属性的内存空间;2. 编译器调用合适的构造函数用于初始化;3. 最后返回指向分配空间的指针。
对于alloc.allocator内部仅调用了operator new函数。
三、 new 和 delete 的重载
在头文件new中,定义了8个重载的operator new 和 delete函数, 其中前四个对应的new 在分配失败的时候会发出bad_alloc异常.后四个对应的new,在分配失败的时候会返回空指针,不会发出异常。
// these versions might throw an exception
void *operator new(size_t); // allocate an object
void *operator new[](size_t); // allocate an array
void *operator delete(void*) noexcept; // free an object
void *operator delete[](void*) noexcept; // free an array
// versions that promise not to throw;
void *operator new(size_t, nothrow_t&) noexcept;
void *operator new[](size_t, nothrow_t&) noexcept;
void *operator delete(void*, nothrow_t&) noexcept;
void *operator delete[](void*, nothrow_t&) noexcept;
四、 malloc/free 和 new/delete 的区别
1. malloc/free 为函数, 而 new/delete为运算符;
2. malloc/free仅仅分配、释放空间; 而new 由两个步骤组成:分配空间(operater new)和调用构造函数(constructor);delete先调用析构函数(destructor)然后释放空间(operator delete);
3. new是类型安全的,而malloc不是。
举例1:不需要强制转换
int *p1 = (int*)malloc(sizeof(int) * length);
int *p2 = new int[length];
举例2:
int *p = new float[2];
int *p= malloc(2*sizeof(float));
4. 在内存不足的时候,malloc返回空指针;而new 发出bad_alloc异常, 在nothrow修饰的时候返回空指针。
参考文献