浅浅记录最近所学关于内存管理的知识点。有兴趣的读者老爷不妨垂阅!
1.C/C++的内存分布
C/C++程序内存区域是有划分的:内核空间、栈、内存映射区、堆、数据段和代码段。如图:
说明:
- 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。
- 堆用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段--存储全局数据和静态数据。
- 代码段--可执行的代码/只读常量。
为了加深理解,俺们不妨做一道题目:
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);
}
选择题:
选项 : A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
- globalVar在哪里?____
- staticGlobalVar在哪里?____
- staticVar在哪里?____
- localVar在哪里?____
- num1 在哪里?____
- char2在哪里?____
- * char2在哪里?___
- pChar3在哪里?____
- * pChar3在哪里?____
- ptr1在哪里?____
- * ptr1在哪里?____
其中以下三条语句很容易混淆:
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
char char2[] = "abcd";的意思是在栈上开辟了5个字节数组char2,所以char2是数组,把"abcd\0"的ASCII码存放到这个数组当中。
const char*pChar3 = "abcd";的意思是有一个存放在代码段的常量字符串"abcd\0"(其实代码段存放的是"abcd\0"的ASCII码),pChar是栈上的一个指针变量,这个指针变量指向常量字符串"abcd\0"的首元素。
int*ptr1 = (int*)malloc(sizeof(int)*4);的意思是使用malloc函数在堆区申请了16个字节的空间,ptr1是栈上的一个指针变量,这个指针变量指向这块堆区开辟的空间的首元素。
画图帮助理解以上三条语句:
答案:
- 选C。globalVar是全局变量,存储在数据段。
- 选C。staticGlobalVar是静态全局变量,存储在数据段。
- 选C。staticVar是静态局部变量,存储在数据段。
- 选A。localVar是局部变量,存储在栈。
- 选A。numl是局部数组,存储在栈。
- 选A。char2是局部数组,存储在栈。
- 选A。*char2是数组char的首元素a,存储在栈。
- 选A。pChar3是局部指针变量,存储在栈。
- 选D。*pChar3是常量区字符串"abcd"的首元素a,存储在代码段。
- 选A。ptr1是局部指针变量,存储在栈。
- 选B。*ptr1是堆区空间首元素。
我们知道C语言中动态内存管理方式:malloc/calloc/realloc/free。C++兼容大部分C语法,所以在C++中也可以使用malloc/calloc/realloc/free。但是有些场景下C语言中动态内存管理方式就不适用了。所以C++有:
2.C++内存管理方式
C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因 此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
new和delete是C++中的关键字,也是操作符,但是都不是函数。
2.1.new/delete操作内置类型
- 申请和释放单个元素的空间,使用new和delete操作符,例如:
#include<iostream>
using namespace std;
int main()
{
/