c++教程(十四:Dynamic memory)

来源:互联网 发布:影楼网络销售工资待遇 编辑:程序博客网 时间:2024/06/07 01:39

————————————————————————

该系列教程为翻译c++官方教程,点击参考英文原版,水平有限,翻译不通之处敬请谅解!

————————————————————————

动态内存

前面的章节可以看到,所有的变量在程序里使用的时候呀都需要事先定义来确定内存。然而有些时候只有程序在运行的时候可能在需要定义内存。例如当我们需要确定用户输入的时候。这种时候,程序可以动态的产生内存。这时,c++提供操作符new和delete。

操作符new和new[]

动态内存可以使用操作符new。New是一种特殊的数据操作类型,如果一段语句至少包含一个元素的时候,可是使用中括号[]。它返回的是new所指向的起始地址的指针。模型如下:

pointer = new typepointer = new type [number_of_elements]

第一句声明一个单一内存的数据type。第二句声明一个type数据块(一个数组),其中number_of_elements是包含数据的总数。例如:

int * foo;foo = new int [5];

这是系统动态的分配包含5个int类型的数组,并返回指向第一个元素地址的指针,也就是存在foo中的指针。因此foo现在指向的是包含着5个int元素的空间。
这里写图片描述
这里foo是一个指针,因此foo的第一个元素就可以通过foo[0]或者foo来表示(两者相同),第二个元素可以表示为foo[1],或者(foo+1),以此类推。
动态数组与一般数组的典型不同在于使用了关键字new。最重要的不同就是标准数组使用的是常量表达式,也就是说它的内存大小在编程的时候就已经知道了。
然而加上new的动态内存可以在运行的时候根据变量值得类型大小来确定。
由我们的程序请求的动态内存是由内存堆分配的。然而,计算机内存是有限的,它可以耗尽。因此,根据不同的系统,保证不了所有的请求都可以分配内存使用。

C++提供了两个标准的机制来检查是否配置成功:
一个是通过处理异常。使用这种方法,当分配失败的时候抛出bad_alloc类型。在后面教程里可以看到异常的是一个强大的C++特性。但现在,你应该知道,如果这个异常被抛出,它不是由一个特定的处理程序处理,该程序执行被终止。

异常方法是new默认的方法,在声明中使用的方法:

foo = new int [5];  // if allocation fails, an exception is thrown 

另一种方法被称为nothrow,当一个内存分配失败就会发生,而不是抛出一个bad_alloc异常或终止程序,new返回的指针是一个空指针,程序继续执行正常。

foo = new (nothrow) int [5];
在这种情况下,如果该块内存分配失败,可以通过检查Foo是否是一个空指针检测:

int * foo;foo = new (nothrow) int [5];if (foo == nullptr) {  // error assigning memory. Take measures.}

这个 nothrow的方法可能没有异常高效,因为这意味着在检查之后,指针需要分配返回值。因此,异常机制通常是首选,至少在关键的分配上。不过,未来大多数例子将使用nothrow机构由于其简单性。

操作符delete和delete[]

在大多数情况下,动态分配的内存只需要在特定的时间内存在,在一个程序中,一旦它不再需要,它可以被释放,使内存成为可用的动态内存供其他程序请求。这是操作符delete的目的,其语法是:

delete pointer;delete[] pointer;

第一句就是删除一个单一的new创建的pointer内存。第二句是删除删除一个new创建的数组内存块。
Delete操作的参数应该是一个指向内存的指针,一个new分配的内存,或一个空指针(在一个空指针的情况下,delete没有影响)。

/ rememb-o-matic#include <iostream>#include <new>using namespace std;int main (){  int i,n;  int * p;  cout << "How many numbers would you like to type? ";  cin >> i;  p= new (nothrow) int[i];  if (p == nullptr)    cout << "Error: memory could not be allocated";  else  {    for (n=0; n<i; n++)    {      cout << "Enter number: ";      cin >> p[n];    }    cout << "You have entered: ";    for (n=0; n<i; n++)      cout << p[n] << ", ";    delete[] p;  }  return 0;}

注意,new语句中的括号中的值是由用户输入的变量值(i),而不是常量表达式:

p= new (nothrow) int[i];

总有可能用户输入了一个值太大,系统不能为它分配足够的内存。例如,当我试图在“How many numbers”后面输入10亿的时候,系统无法分配多少内存的程序,那么就会得到文本消息,这种情况下就会产生错误(错误:内存不能分配)。

在编程的时候能够处理故障分配内存是很好的,要么通过检查指针的值(如果不抛出)或通过捕捉适当的异常。

C中的动态内存:

C++集成运营商动态分配内存采用new和delete。但这些在C语言中没有;相反,它使用一个库的解决方案,使用函数malloc,calloc,realloc和free,在头文件(称为

0 0