C++ 内存管理



C++ 中的动态内存分配

以下是任何 C++ 程序使用的基本内存架构:

C++程序内存架构
  • 代码段:编译后的程序执行指令在代码段中,它是只读的。
  • 数据段:全局变量和静态变量保存在数据段中,它不是只读的。
  • :栈通常是预先分配的内存,堆栈是一种后进先出(LIFO)数据结构,在调用函数或块结束后,系统会清除栈上保存的局部变量、函数调用信息及其他信息。
  • :在程序运行期间动态分配内存,堆是先进先出(FIFO)数据结构,使用 new 运算符分配内存,使用 delete 运算符释放内存。


使用 new 关键字分配堆内存

在这里,我们将学习如何使用 new 关键字为变量或类对象分配堆内存。 语法:

数据类型 *指针名 = new 数据类型

例如:

int *new_op = new int;
// 分配一块内存
int *new_op = new int[10];

如果 中没有足够的内存可用,则会抛出 std::bad_alloc 类型的异常。



使用 delete 关键字释放内存

一旦使用 new 关键字将堆内存分配给变量或类对象,我们就可以使用 delete 关键字释放该内存空间。 语法:

delete 指针名

例如:

delete new_op;


理解 C++ 中的内存泄漏

内存泄露是申请了一块内存而忘记了释放,结果导致这块内存一直被占用,如果内存泄露太多,如程序长时间运行或操作,导致系统内存升高,造成电脑卡顿直至程序崩溃。

C++中没有像java中那样的自动垃圾回收机制,因此程序员要负责内存的释放,即使是经验丰富的程序员,也可能会内存泄露,所以申请的内存一定要记得释放。

通过使用 delete 关键字,我们可以删除分配的内存: 例如:

*ex= new Example();
delete ex;

但在上面的示例中,可能会发生 野指针 问题。等等,什么是野指针?



什么是野指针?

野指针也叫悬空指针,是指原申请的指针内存已经释放而指针未置空或声明了一个指针没有置空也没有分配内存。 C++野指针

  • 在第一个图中,指针的内存位置1100,它里面有个25的值。
  • 在第二个图中,指针指向内存位置已经被释放。

野指针一般是由于对象释放而产生的,当对象被删除或释放时,并没有修改指针的值或置为NULL,因此指针还指向原来的内存位置,这个问题可以通过将指针的值赋为NULL来避免。 例如:

*ex = new Example();
Delete ex;
// 将指针重新赋值为NULL
ex = NULL;


什么是智能指针?

智能指针用于管理动态分配对象的生命周期,它们确保正确销毁动态分配的对象,智能指针在头文件中定义。

智能指针是内置指针,我们不必担心忘记删除它们,它们会自动删除。

下面是一个智能指针的例子:

S_ptr *ptr = new S_ptr();
ptr->action();
delete ptr;