在 C
语言中,可以用库函数
malloc()
来分配内存;在
C++
中仍然可以这样做,但
C++
还有更好的方法——new
运算符
语法
类型* 指针名 = new 类型;
//可以赋初值
类型* 指针名 = new 类型(初值);
类型* 指针名 = new 类型{初值};
//连续空间
类型* 指针名 = new 类型[元素个数];
delete 指针名;
示例:
int *a = new int; //创建一个整型空间
void *b = new int;//用 void 指向
char *c = new char('c'); //创建一个字符型空间并赋初值
int *d = new int [10]; //创建一个 10 个元素的整型空间
A *e = new A(10);//创建一个类并赋初值
B *f = new B; //创建一个结构体空间
//释放
delete a;
delete b;
delete c;
delete d;
delete e;
delete f;
new(std::nothrow)使用
一般我们平常直接使用 new
的时候,在
内存
分配失败的时候直接报异常,也就是说分配失败的时候会抛出 std::bad_alloc
错误,不会将指针置空。而
new (std::nothrow)
在内存不足时,并不抛出异常,而是将指针置 NULL
。
std::nothrow
可以实现对非零指针的检查。 在操作符new 和
new [ ]
内存分配失败的时候抛出的异常,在分配异常的情况下这时的指针
myarray
不为 NULL
;没法用进行
Test-for-NULL
检查,
Test-for-NULL
这是个好习惯。
#include <iostream> // std::cout
#include <new> // std::bad_alloc
int main()
{
char *p;
int i = 0;
try
{
do
{
p = new char[1024 * 1024]; //每次 1M
i++;
} while (p);
}
catch(std::exception &e)
{
std::cout << e.what() << "\n" << "分配了" << i << "M" << std::endl;
};
//x86 :
// bad allocation
// 分配了 1893M
long num = 0x7fffffff; //0x7fffffff = 2,147,483,647 = 2047*1024*1024 = 2047M
char* myarray = nullptr;
try
{
//vs2015 x86 error C2148: 数组的总大小不得超过 0x7fffffff 字节
myarray = new char[2047 * 1024 * 1024]; ///1024 * 1024 * 1024
}
catch (std::bad_alloc &ba)
{
std::cerr<< "bad_alloc caught: " << ba.what() << '\n'; //bad_alloc caught: bad allocation
}
delete[] myarray;
return 0;
}
如上,当使用 new 或 new []分配空间不足时,就会抛出异常,但是指针并不会置空,这样就会给这个指针后续的判断使用存在一些隐患。
而使用 new(std::notheow)在分配失败的时候就不会抛出异常,而是直接将该指针置空,后续你只需要判断这个指针是否为空就可以知道 new 分配成功与否,例如
int main()
{
char *p= NULL;
int i = 0;
do
{
p = new (std::nothrow) char[1024 * 1024]; //每次 1M
i++;
} while (p);
if (NULL == p)
{
std::cout << "分配了 " << i - 1 << " M 内存" //分配了 1890 Mn 内存第 1891 次内存分配失败
<< "第 " << i << " 次内存分配失败";
}
long num = 0x7fffffff; //0x7fffffff = 2,147,483,647 =
2047*1024*1024 = 2047M
char* myarray = nullptr;
//vs2015 x86 error C2148: 数组的总大小不得超过 0x7fffffff 字节
myarray = new (std::nothrow)char[2047 * 1024 * 1024]; ///1024 * 1024 * 1024
if (nullptr == myarray)
{
std::cerr << " new (std::nothrow)char[2047 * 1024 * 1024] 内存分配失败" << std::endl;
}
else
{
std::cout<<" new (std::nothrow)char[2047 * 1024 * 1024] 内存分配成功" << std::endl;
}
return 0;
}
在实际开发中,内存的分配失败是非常普通的,它们通常在植入性和不支持异常的可移动的器件中发生更频繁。因此,应用程序开发者在这个环境中使用 nothrow new
来替代普通的new 可以更加安全!
new 和 malloc 的区别
1. new
是操作符,而
malloc
是函数
2. new
在调用对类的创建时先分配内存,再调用构造函数,释放的时候调用析构函数。
3. new
是类型安全的,
malloc
返回默认是
void*
4. new
可以被重载
5. new
分配内存更直接和安全
6
.
malloc
可以被
realloc
7.new
发生错误抛出异常,
malloc
返回
null
8. malloc
可以分配任意字节,
new
只能分配实例所占内存的整数倍数大小