new is an operator for dynamic memory allocation in C++, and the malloc function is generally used in C language .
(1) plain new, as the name suggests, is ordinary new, which is the new we usually use. Non-allocated memory, calling the constructor , is defined in C++ as follows:
void* operator new(std::size_t) throw(std::bad_alloc);
void operator delete(void *) throw();
Plain new throws an exception std::bad_alloc instead of returning NULL in the case of an allocation failure, so it is futile to judge whether the return value is NULL.
#include <iostream>
using namespace std;
char *GetMemory(unsigned long size)
{
char *p=new char[size];//Allocation failed, not returning NULL
return p;
}
int main()
{
try
{
char *p=GetMemory(10e11);//Allocation failed throw exception std::bad_alloc //..........if(!p)//In
vain
cout
< <"failure"<<endl;
delete [] p;
}
catch(const std::bad_alloc &ex)
{
cout<<ex.what()<<endl;
}
return 0;
}
(2) nothrow new is a form of operator new that does not throw exceptions. nothrow new returns NULL on failure . It is defined as follows:
void * operator new(std::size_t,const std::nothrow_t&) throw();
void operator delete(void*) throw();
#include <iostream>
#include <new>
using namespace std;
char *GetMemory(unsigned long size)
{
char *p=new(nothrow) char[size];//Allocation fails, it returns NULL
if(NULL==p)
cout<<"alloc failure!"<<endl;
return p;
}
int main()
{
try
{
char *p=GetMemory(10e11);
//...........
if(p==NULL)
cout<<"failure"<<endl;
delete [] p;
}
catch(const std::bad_alloc &ex)
{
cout<<ex.what()<<endl;
}
return 0;
}
(3) placement new means "placement", which allows to reconstruct an object or an array of objects on a block of memory that has been allocated successfully. placement new doesn't have to worry about memory allocation failures because it doesn't allocate memory at all, the only thing it does is call the object's constructor . It is defined as follows:
void* operator new(size_t,void*);
void operator delete(void*,void*);
The main use of palcement new is to repeatedly use a larger piece of dynamically allocated memory to construct different types of objects or their arrays. Objects or their arrays constructed by placement new are to be explicitly destroyed by calling their destructors. Never use delete.
#include <iostream>
#include <new>
using namespace std;
class ADT
{
int i;
int j;
public:
ADT()
{
}
~ADT()
{
}
};
int main()
{
char *p=new(nothrow) char[sizeof(ADT)+2];
if(p==NULL)
cout<<"failure"<<endl;
ADT *q=new(p) ADT; //placement new: Don't worry about failure
// delete q;//Error! Can't call delete q here;
q->ADT::~ADT();//Show call destructor
delete []p;
return 0;
}
Other:
When using the new operator to define a multidimensional array variable or array object, it yields a pointer to the first element of the array, and the returned type holds all but the leftmost dimension. E.g:
int *p1 = new int[10];
Returns a pointer to an int int*
int (*p2)[10] = new int[2][10];
A two-dimensional array is new, and the leftmost one-dimensional [2] is removed, leaving int[10], so what is returned is a pointer to a one-dimensional array such as int[10] int (*)[10].
int (*p3)[2][10] = new int[5][2][10]; new a three-dimensional array, remove the leftmost dimension [5], and int[2][10], So what is returned is a pointer to a two-dimensional array of type int[2][10] int (*)[2][10].
#include<iostream>
#include <typeinfo>
using namespace std;
int main() {
int *a = new int[34];
int *b = new int[];
int (*c)[2] = new
int[34][2];
int (*d)[2] = new int[][2];
int (*e)[2][3] = new int[34][2][3];
int (*f)[2][3] = new int[][2][3];
a[0] = 1;
b[0] = 1; //Runtime error, no allocated memory, b only acts as a pointer to point to the corresponding data
c[0][0] = 1;
d[0][0] = 1;//Runtime error, no allocated memory, d only acts as a pointer to point to the corresponding data
e[0][0][0] = 1;
f[0][0][0] = 1;//Runtime error, no allocated memory, f only acts as a pointer to point to the corresponding data
cout<<typeid(a).name()<<endl;
cout<<typeid(b).name()<<endl;
cout<<typeid(c).name()<<endl;
cout<<typeid(d).name()<<endl;
cout<<typeid(e).name()<<endl;
cout<<typeid(f).name()<<endl;
delete[] a; delete[] b; delete[] c;
delete [] d; delete [] e; delete [] f;
}
Output result:
int *
int *
int (*)[2]
int (*)[2]
int (*)[2][3]
int (*)[2][3]