在C++中对象既可以动态分配内存,也可以静态分配内存。
- 静态分配:在程序运行之前进行,分配效率较高;
- 动态分配:用于存储未知数目的元素,灵活性较高;
动机
- 程序不知道自己需要使用多少对象;
- 程序不知道所需对象的准确类型;
- 程序需要在多个对象间共享数据;
区别
-
静态对象有名字,而动态对象没有名字;
-
静态对象可以直接操作,动态对象需要通过指针间接操作;
-
静态对象空间的处理与释放由编译器自动处理,而动态对象的空间分配与释放需要程序员显示处理;
new
new运算符在堆上分配空间,创建对象,并返回对象地址。一般将new对象返回的地址保存在指针变量,以便访问堆上的对象。
int* p1 = new int;//在堆上分配一个int类型,并且保存其地址
*p1 = 128;//通过指针间接操作
int* p2 = new int(100);//在堆上分配一个初始值为100的int类型,并且返回其地址
int* pa = new int[100];//在堆上分配一个大小为100的int数组,并且返回其首地址
- new 分配的数组大小并非常量,可以在程序运行期间指定;
- 用new分配的内存被成为动态内存,但并不是真正的数组类型;
- 用new分配数组时,得到的是一个数组元素类型的指针;
在指针指向的空间中创建一个指定类型的对象时,程序员可以预先分配大量内存,而后通过定位new表达式在这段内存中创建对象。使用定位new,必须包含标准库头文件。
# include <iostream>
# include <new>
using namespace std;
char* buf = new char[1000];//预分配一段内存,首地址在buf中保存
int main(){
int* p = new (buf) int;//在buf中创建一个int对象,不在重新从堆上分配空间
}
delete
堆上的空间在使用后必须释放,否则会造成内存泄漏。
int* p = new int;
*p = 128;
delete p;
/*
执行delet后,p指向的空间被释放,不能使用p指向的内存(先前),p变量自己的存储空间不受影响。
p指针被称为空悬指针,即指向不确定的单元。
*/
int x;
p = &x;//将p指向x
管理动态内存三大问题
- 忘记delete内存
- 使用已经释放掉的对象
- 同一块内存被释放两次