C++ new和delete的用法(附带实例)
C++ 程序中定义一个变量后,其值会被放入内存中。读者是否好奇,变量的值到底被存放在哪里?
如果开发者未向系统申请动态内存,变量的值将会被放入栈中。在栈中,变量占用的内存大小是无法改变的,它们的占用与释放与变量定义的位置和储存方式有关。
与栈相对应,堆是一种动态内存。当开发者向系统申请了动态分配内存,该变量将会被放入堆中。根据需要,这个变量的内存大小可以改变,内存申请和释放的时机由开发者操控。
C++ 中,new 用于申请动态堆内存空间,delete 用于释放动态堆内存空间。
使用 new 关键字申请堆内存空间的方式如下:
【实例 1】动态分配空间。定义一个指针变量,通过 new 关键字为其分配内存空间,代码如下:
程序运行结果为:
动态分配方式虽然灵活,但也带来了新的问题。开发者申请堆内存后,这块内存将由开发者掌握,也就是说系统无法自动释放它,只有开发者使用 delete 关键字才能将其回收。
【实例 2】释放内存。使用 new 关键字分配内存,用完之后进行释放,输出分配内存的地址以及释放内存之后的地址,具体代码如下:
如果开发者未向系统申请动态内存,变量的值将会被放入栈中。在栈中,变量占用的内存大小是无法改变的,它们的占用与释放与变量定义的位置和储存方式有关。
与栈相对应,堆是一种动态内存。当开发者向系统申请了动态分配内存,该变量将会被放入堆中。根据需要,这个变量的内存大小可以改变,内存申请和释放的时机由开发者操控。
C++ 中,new 用于申请动态堆内存空间,delete 用于释放动态堆内存空间。
使用 new 关键字申请堆内存空间的方式如下:
p1 = new type; // 使用 new 关键字申请堆内存,并将指针 p1 指向它其中,p1 表示指针,new 是关键字,type 是类型名。new 返回新分配的内存单元的地址。
【实例 1】动态分配空间。定义一个指针变量,通过 new 关键字为其分配内存空间,代码如下:
#include <iostream> using namespace std; int main() { int *p1 = NULL; // 定义指针 p1 p1 = new int; // 申请一块动态内存(堆),p1 指向它 *p1 = 111; // 将 111 存入堆内存空间 cout << "p1 内存的内容" << *p1 << "," << p1 << "所指向的地址" << p1 << endl; int *p2; int k; p2 = &k; // 为变量 k 分配栈内存,p2 指向它 *p2 = 222; // 分配内存后方可赋值 cout << "p1 内存的内容" << *p2 << "," << p2 << "," << p1 << endl; return 0; }可以看到,指针 p1 创建后申请了动态分配,程序自动分配给它一块堆内存。而指针 p2 则获取了栈中的内存地址,属于静态分配。
程序运行结果为:
p1 内存的内容111,0x161510所指向的地址0x161510
p1 内存的内容222,0x6ffdfc,0x161510
动态分配方式虽然灵活,但也带来了新的问题。开发者申请堆内存后,这块内存将由开发者掌握,也就是说系统无法自动释放它,只有开发者使用 delete 关键字才能将其回收。
【实例 2】释放内存。使用 new 关键字分配内存,用完之后进行释放,输出分配内存的地址以及释放内存之后的地址,具体代码如下:
#include <iostream> using std::cout; using std::endl; int *newPointerGet(int *p1) // 定义函数 newPointerGet() { int k1 = 55; p1 = new int; // 申请一块动态内存(堆),p1 指向它 *p1 = k1; // 将 k1 存入堆内存空间 return p1; } int *PointerGet(int *p2) // 定义函数 PointerGet() { int k2 = 55; p2 = &k2; // p2 表示的栈内存中存放 k2,此内存在函数执行后会被系统销毁 return p2; } int main() { cout << "输出函数各自返回指针所指向的内存的值" << endl; int *p = NULL; p = newPointerGet(p); // p 具有堆内存的地址 int *i = NULL; i = PointerGet(i); // i 具有栈内存地址,内存内容被销毁 cout << "newGet: " << *p << "," << p << endl; cout << "i 所指向的内存没有被立刻销毁,执行一个输出语句后:" << endl; cout << "iGet: " << *i << "," << i << endl; // 仍然为 55,但不代表程序不对它进行销毁 delete p; // 执行其他语句后,程序销毁了栈空间 cout << "销毁堆内存后:" << endl; cout << "p: " << *p << endl; return 0; }程序运行结果为:
输出函数各自返回指针所指向的内存的值
newGet: 55,0xba1510
i 所指向的内存没有被立刻销毁,执行一个输出语句后:
iGet: 0,0x6ffdcc
销毁堆内存后:
p: 12196368