C++ 程序在运行时,计算机内存被分为程序代码区、全局数据区、堆区、栈区四个部分。
本文一是介绍 C++ 三种内存分配方式,二是使用 new 关键字和 delete 关键字管理堆内存。
C语言堆区内存管理移步:【堆区内存管理】堆区(heap)内存操作: malloc()
、calloc()
、memcpy()
、memset()
和 free()
函数操作堆区内存
目录
- 内存分配的三种方式
静态存储分配
内存分配
内存分配
- C++堆内存管理
new 关键字
delete 关键字
1. 内存分配的三种方式
不同的内存分配方式,有不同的内存调度机制。
C++ 语言的三种内存分配方式分别是:静态存储区分配、栈内存分配和堆内存分配。
1.1 静态存储区分配
-
定义:在程序编译时分配的内存,存在于程序的整个运行过程。
例如: static 变量,其生命周期随程序的结束而结束,而非像一般变量随函数或作用域的结束而结束。
除了 static 变量,还有一种全局对象 static object,也可以存放在静态存储区。
1.2 栈内存分配
-
定义:内存是存在于某作用域(局部变量)的一块空间,函数调用时分配栈内存,按照后进先出(LIFO)原则管理。
-
生命周期:起于变量声明,止于函数执行结束。
例如:调用某个函数时,函数内局部变量的存储单元可以在栈上创建,函数执行结束时,这些内存单元会被自动释放;
-
特点:
- 自动管理:栈内存的分配和释放由编译器自动管理,无需程序员手动干预。
- 存储限制:栈的大小通常有限,过多的局部变量可能导致栈溢出。
-
内存位置:存放在栈区,栈区位于内存的高地址区域。
1.3 堆内存分配
-
定义:也称 动态内存分配,使用
malloc
、calloc
、realloc
、free
(C)或new
、delete
(C++)进行管理。 -
生命周期:用户可以手动分配和释放内存,生存周期由用户决定,灵活性高。
-
特点
- 灵活性:可以根据需要动态调整内存大小。
- 内存碎片:频繁的分配和释放可能导致内存碎片,影响性能。
- 手动管理:需要程序员显式释放不再使用的内存,避免内存泄漏。
-
内存位置:存放在堆区,通常在内存的中间区域。
1.4 总结
- 静态存储区分配适合不需要改变的全局或静态变量,生命周期长。
- 栈内存分配适用于局部变量,自动管理,使用方便,但空间有限。
- 堆内存分配灵活性高,适合动态需求,但需要手动管理内存。
2. C++堆内存管理
C 语言: malloc() 函数来分配内存空间,free() 函数来释放内存空间。
C++ 语言: new 关键字来分配内存空间,delete 关键字来释放内存空间。后者在性能等方面优于前者。
在学习使用 new 和 delete 关键字之前我们先初步了解一下指针的概念及其一般形式。
2.1 预知:指针
指针是一个变量,其值是另一个变量的地址。指针变量声明的一般形式为:
type *pointerVar-name
其中 type
为指针的数据类型,*
是定义指针的关键符,pointerVar-name
指定指针变量名。
例如:char *p
,即定义了一个字符型指针变量 p。
指针的另一些基本内容会在后续的实验中详细介绍,本次实验对指针的内容仅做了解。现在我们正式学习 new 关键字和 delete 关键字。
2.2 new 关键字
new 关键字 用于堆内存的分配,可自动计算所要分配内存空间的大小,其基本使用形式为:
指针变量名 = new 类型
例如:
int *p; //定义一个整型指针变量
p = new int;
其中 p = new int;
表示动态分配一个存放整型数据的内存空间,并将其首地址赋给整型指针变量 p,此时省略指针变量 p 前的 *
。
2.3 delete 关键字
delete 关键字 用于堆内存的释放,其基本形式为:
delete 指针变量
例如:
int *p; //定义一个整型指针变量
p = new int;
//省略指针操作过程
delete p;
其中 delete p;
表示释放指针变量 p 指向的内存空间,此时省略指针变量 p 前的 *
。
注意:使用 new 获取的内存空间必须使用 delete 进行释放。
我们用实例来加深一下 new 和 delete 关键字的使用方式,新建 mans.cpp
文件,输入:
#include <iostream>
using namespace std;
int main()
{
int *p; //定义一个整型的指针变量 p。
p = new int; //动态分配一个存放整型数据的内存空间,并将其首地址赋给整型指针变量 p。
*p = 6; //为指针指向的内存块赋值为 6。
cout<<*p<<endl; //输出内存块的赋值。
delete p;//释放指针变量 p 指向的内存空间。
return 0;
}
程序首先定义了整型指针变量 p,然后使用 new 关键字为其分配 int 型的内存空间,并让指针 p 指向分配的内存空间。随后为内存块赋值为 6,并且输出所赋的值。最后释放指针变量 p。
程序结果为:
name: 检查目录是否创建
script: |
#!/bin/bash
ls /home/project/mans.cpp
error: 未创建 mans.cpp 文件
timeout: 1
- name: 检查文件内容
script: |
#!/bin/bash
grep delete /home/project/mans.cpp
error: 内存分配有误
timeout: 2