C++ 程序中的内存分为两个部分:
栈:在函数内部声明的所有变量都将占用栈内存。
堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。
在 C++ 中,我们可以使用new运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。如果不再需要动态分配的内存空间,可以使用 delete 运算符,删除之前由 new 运算符分配的内存。
1.new和delete的常规简要用法
new 运算符来为任意的数据类型动态分配内存的通用语法:
1 new data-type;
其中,data-type可以是包括数组在内的任意内置的数据类型,也可以是包括类或结构在内的用户自定义的任何数据类型。例如我们可以定义一个指向int类型数据的指针p,然后请求内存,该内存在执行时被分配。
1 int* p = NULL; // 初始化为null的指针 2 p = new int; // 为变量请求内存
如果自由存储区已被用完,可能无法成功分配内存。所以建议检查 new 运算符是否返回 NULL 指针,并采取以下适当的操作:
1 int* p = NULL; 2 if (!(p = new int)) 3 { 4 cout << "Error: out of memory." << endl; 5 exit(1); 6 7 } 8 p = new int;
如果某个已经动态分配内存的变量不再需要使用时,我们可以使用 delete 操作符释放它所占用的内存,如下所示:
1 delete p; // 释放p所指向的内存
new和delete完整用法示例:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int* p = NULL; // 初始化为 null 的指针 7 p = new int; // 为变量请求内存 8 *p= 12345; // 在分配的地址存储值 9 cout << "Value of p : " << *p << endl; 10 delete p; // 释放内存 11 return 0; 12 }
运行结果:
1 Value of p : 12345
2.数组的动态内存分配
(1)一维数组:
1 // 动态分配,数组长度为 n 2 int *array=new int [n]; 3 4 //释放内存 5 delete [] array;
(2)二维数组:
1 int **array 2 // 假定数组第一维长度为 m, 第二维长度为 n 3 // 动态分配空间 4 array = new int *[m]; 5 for( int i=0; i<m; i++ ) 6 { 7 array[i] = new int [n] ; 8 } 9 //释放 10 for( int i=0; i<m; i++ ) 11 { 12 delete [] arrary[i]; 13 } 14 delete [] array;
二维数组实例测试:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int** p; 7 int i, j; //p[4][8] 8 //开始分配4行8列的二维数据 9 p = new int* [4]; 10 for (i = 0; i < 4; i++) 11 { 12 p[i] = new int[8]; 13 } 14 15 for (i = 0; i < 4; i++) 16 { 17 for (j = 0; j < 8; j++) 18 { 19 p[i][j] = j * i; 20 } 21 } 22 //打印数据 23 for (i = 0; i < 4; i++) 24 { 25 for (j = 0; j < 8; j++) 26 { 27 if (j == 0) 28 { 29 cout << endl; 30 } 31 cout << p[i][j] << " "; 32 } 33 } 34 //开始释放申请的堆 35 for (i = 0; i < 4; i++) 36 { 37 delete[] p[i]; 38 } 39 delete[] p; 40 return 0; 41 }
代码运行结果:
(3)三维数组:
1 int*** array; 2 // 假定数组第一维为 m, 第二维为 n, 第三维为h 3 // 动态分配空间 4 array = new int** [m]; 5 for (int i = 0; i < m; i++) 6 { 7 array[i] = new int* [n]; 8 for (int j = 0; j < n; j++) 9 { 10 array[i][j] = new int[h]; 11 } 12 } 13 //释放 14 for (int i = 0; i < m; i++) 15 { 16 for (int j = 0; j < n; j++) 17 { 18 delete[] array[i][j]; 19 } 20 delete[] array[i]; 21 } 22 delete[] array;
三维数组测试实例:
1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 int i, j, k; // p[2][3][4] 7 8 int*** p; 9 p = new int** [2]; 10 for (i = 0; i < 2; i++) 11 { 12 p[i] = new int* [3]; 13 for (j = 0; j < 3; j++) 14 { 15 p[i][j] = new int[4]; 16 } 17 } 18 19 //输出 p[i][j][k] 三维数据 20 for (i = 0; i < 2; i++) 21 { 22 for (j = 0; j < 3; j++) 23 { 24 for (k = 0; k < 4; k++) 25 { 26 p[i][j][k] = i + j + k; 27 cout << p[i][j][k] << " "; 28 } 29 cout << endl; 30 } 31 cout << endl; 32 } 33 34 // 释放内存 35 for (i = 0; i < 2; i++) 36 { 37 for (j = 0; j < 3; j++) 38 { 39 delete[] p[i][j]; 40 } 41 } 42 for (i = 0; i < 2; i++) 43 { 44 delete[] p[i]; 45 } 46 delete[] p; 47 return 0; 48 }
代码运行结果:
3.对象的动态内存分配
示例代码:
1 #include <iostream> 2 using namespace std; 3 4 class test 5 { 6 public: 7 test() { 8 cout << "调用构造函数!" << endl; 9 } 10 ~test() { 11 cout << "调用析构函数!" << endl; 12 } 13 }; 14 15 int main() 16 { 17 test* testArray = new test[4]; 18 delete[] testArray; // 删除数组 19 return 0; 20 }
代码运行结果:
如果要为一个包含四个test对象的数组分配内存,构造函数将被调用 4 次,同样地,当删除这些对象时,析构函数也将被调用相同的次数(4次)。