什么是内存管理
内存的本质什么: 资源
谁掌握内存资源: 操作系统
我们能做什么呢: 申请/归还
内存的申请和释放
运算符:
申请内存: new
释放内存: delete
申请和释放内存的方法:
申请内存: int *p = new int;
释放内存: delete p;
如何申请和释放内存块呢?
申请块内存: int *arr = new int[10];
释放块内存: delete []arr;
注意事项
1、C语言和C++的内存申请方式不要混淆
C语言中内存管理的方式:
申请内存: void *malloc(size_t size);
释放内存: void free(void *memblock);
如果使用C语言的方式,就使用malloc和free组合,不要跟C++的new和delete混淆。
2、判断是否申请内存失败
有的时候系统的内存不足,而你申请的内存过大时,这时候你申请内存可能就会失败。
所以你需要判断一下:
int *p = new int; if(NULL == p) // 判断内存申请是否成功 { // to do }
3、释放内存时的注意事项
释放完内存后,要把指针置为空,避免一些不可预见的错误
int *p = new int; if(NULL == p) { // 内存分配失败 // 异常处理 } delete p; p = NULL;
int *p = new int[1000]; if(NULL == p) { // 内存分配失败 // 异常处理 } delete []p; p = NULL;
提问
auto ch0 = new char[10]; auto stu = new Student[10]; delete ch0; //1 delete []ch0; //2 delete stu; //3 delete []stu; //4
问题是上述几个delete中哪个是错误的呢?很多人都会说1和3是错误的,因为申请了数组而释放的时候要像2和4那样进行释放。其实第一个不会发生内存泄漏。因为只有在申请自定义的对象如果不用数组释放方法进行释放才会发生内存泄漏。而内置的变量时不会的。但是也要成对应用,规范的使用运算符
auto ch0 = new char; // 1 auto ch1 = new char(); // 2
这两行代码有什么区别呢?一个加了括号一个没有加。那么它们的运行是一样的么?显然是不一样的,1行是没有进行初始化的。而2行是进行了初始化。如果我们申请的变量在一开始没有决定如何进行初始化时,不妨就不要初始化。等程序真正要初始化的时候我们再进行初始。这样我们就会少进行一次赋值操作。
实例练习:
练习1:
#include <iostream> #include <stdlib.h> using namespace std; int main(void) { int *p = new int(20); // 进行了初始化 // int *p = new int; // *p = 20 // 申请内存时不进行初始化,随后赋值 cout << *p << endl; system("pause"); return 0; }
练习2:
#include <iostream> #include <stdlib.h> using namespace std; int main(void) { int *p = new int; if(NULL == p) // 判断内存申请是否成功 { system("pause"); return 0; } *p = 20; cout << *p << endl; delete p; // 释放指针 p = NULL; // 将p指针设为空 system("pause"); return 0; }
练习3:
申请块内存
#include <iostream> #include <stdlib.h> using namespace std; int main(void) { int *p = new int[100]; if(NULL == p) // 判断内存申请是否成功 { system("pause"); return 0; } p[0] = 10; p[1] = 20; cout << p[0] << "," << p[1] << endl; delete []p; // 释放指针时必须用 []p,如果用p,只能释放块指针的第一个 p = NULL; // 将p指针设为空 system("pause"); return 0; }