动态内存分配
Why?
可以保证程序在运行过程中按照实际需要申请适量的内存,使用结束后还可以释放,这种在程序运行过程中申请和释放的存储单元也称为堆对象,申请和释放的过程一般称为建立和删除。
new的功能:动态分配内存,或称为动态创建堆对象
new 数据类型(初始化参数列表)
-
- 如果内存申请成功,new运算返回一个指向新分配内存首地址的类型的指针,可通过这个指针对堆对象访问;
- 如果失败,会抛出异常。
建立的对象是基本类型变量
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 int main() 4 { 5 int *p1 = new int; //分配内存后不设定初值 6 int *p2 = new int();//表示用0对该对象初始化 7 8 //动态分配用于存放int类型数据的内存空间,并将初值2存入内存空间,然后将首地址赋给指针p3 9 int *p3 = new int(4); 10 11 cout << *p1 << endl; 12 cout << *p2 << endl; 13 cout << *p3 << endl; 14 return 0; 15 }
建立的对象是某一个类的实例对象
如果用户定义了默认构造函数:new T和new T( )效果相同
如果没有:new T会调用系统生成的隐含的默认构造函数;
new T( )除了执行默认构造函数会执行的操作之外,还会为基本数据类型和指针类型的成员用0赋值,而 且这一过程是递归的。
delete:删除由new建立的对象,释放指针所指向的内存空间
detele 指针名;
如果同一内存空间多次使用delete进行删除,会导致运行错误。
使用new分配的内存,必须用delete释放,否则会导致动态分配的内存单元无法回收,使得程序占据的内存越来越大,这叫做内存泄漏。
动态创建对象:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 4 class Point{ 5 public: 6 Point() :x(0), y(0)//默认构造函数 7 { 8 cout << "constructor1" << endl; 9 } 10 Point(int x, int y) :x(x), y(y) 11 { 12 cout << "constructor2" << endl; 13 } 14 ~Point() 15 { 16 cout << "destructor" << endl; 17 } 18 int getX() 19 { 20 return x; 21 } 22 int getY() 23 { 24 return y; 25 } 26 void move(int mx, int my) 27 { 28 x += mx; 29 y += my; 30 } 31 private: 32 int x, y; 33 }; 34 35 int main() 36 { 37 Point *p = new Point;//调用默认构造函数 38 delete p; 39 40 p = new Point(6, 7); 41 delete p; 42 43 return 0; 44 }
new创建数组类型的对象
new 类型名 [数组长度];
int *p=new int[10]( );(加括号与否与new T相同,加括号——数组用0初始化)
delete [ ] 指针名;
动态创建对象数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 class Point{ 4 public: 5 Point() :x(0), y(0)//默认构造函数 6 { 7 cout << "constructor1" << endl; 8 } 9 Point(int x, int y) :x(x), y(y) 10 { 11 cout << "constructor2" << endl; 12 } 13 ~Point() 14 { 15 cout << "destructor" << endl; 16 } 17 int getX() 18 { 19 return x; 20 } 21 int getY() 22 { 23 return y; 24 } 25 void move(int mx, int my) 26 { 27 x += mx; 28 y += my; 29 } 30 private: 31 int x, y; 32 }; 33 34 int main() 35 { 36 Point *ptr = new Point[2];//调用构造函数 37 cout << ptr[0].getX() << "," << ptr[0].getY() << endl; 38 cout << ptr[1].getX() << "," << ptr[1].getY() << endl; 39 40 ptr[0].move(3, 4); 41 ptr[1].move(1, 1); 42 43 cout << ptr[0].getX() << "," << ptr[0].getY() << endl; 44 cout << ptr[1].getX() << "," << ptr[1].getY() << endl; 45 46 delete[] ptr;//删除整个对象数组 47 48 return 0; 49 }
动态数组类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cassert> 3 using namespace std; 4 5 class Point{ 6 public: 7 Point() :x(0), y(0)//默认构造函数 8 { 9 cout << "constructor1" << endl; 10 } 11 Point(int x, int y) :x(x), y(y) 12 { 13 cout << "constructor2" << endl; 14 } 15 ~Point() 16 { 17 cout << "destructor" << endl; 18 } 19 int getX() 20 { 21 return x; 22 } 23 int getY() 24 { 25 return y; 26 } 27 void move(int mx, int my) 28 { 29 x += mx; 30 y += my; 31 cout << x << endl; 32 cout << y << endl; 33 34 } 35 private: 36 int x, y; 37 }; 38 39 class PointArray{ 40 public: 41 PointArray(int size) :size(size) 42 { 43 ptr = new Point[size]; 44 } 45 46 ~PointArray() 47 { 48 cout << "析构" << endl; 49 delete[] ptr; 50 } 51 52 Point &getElement(int index) 53 { 54 assert(index >= 0 && index < size);//如果数组下标越界,程序终止 55 return ptr[index]; 56 } 57 58 private: 59 Point *ptr; 60 int size; 61 }; 62 63 64 int main() 65 { 66 int size; 67 cout << "请输入size的大小:" << endl; 68 cin >> size; 69 PointArray pArray(size); 70 71 pArray.getElement(0).move(3, 2); 72 pArray.getElement(1).move(6, 26); 73 74 return 0; 75 }
- assert用来判断一个条件表达式的是否为true,如果不为true,则程序终止,并且报告出错误。
- 一般程序可以以两种模式编译——调试模式和发行模式(debug 和 release),assert只在调试模式下生效,而在发行模式下不执行任何操作。
- asset只检查程序本身的逻辑错误,而用户的不当输入造成的错误,应当用其他方式处理。
- 用new创建多维数组
float *fp;
fp=new float [10] [25] [10];//此方法错误
float (*fp) [25] [10];
fp=new float [10] [25] [10];
动态创建多维数组
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 4 int main() 5 { 6 int(*p)[4][5] = new int[3][4][5]; 7 8 for (int i = 0; i < 3; i++) 9 { 10 for (int j = 0; j < 4; j++) 11 { 12 for (int k = 0; k < 5; k++) 13 { 14 *(*(*(p + i) + j) + k) = i * 100 + j * 10 + k;//p[i][j][k]=i*100+j*10+k 15 } 16 } 17 } 18 19 for (int i = 0; i < 3; i++) 20 { 21 for (int j = 0; j < 4; j++) 22 { 23 for (int k = 0; k < 5; k++) 24 { 25 cout << *(*(*(p + i) + j) + k) << " "; 26 } 27 cout << endl; 28 } 29 cout << endl; 30 } 31 32 delete[] p; 33 return 0; 34 }
-Megan