C++ || C/C++内存管理 | C++动态内存管理方式 | operator new/delete函数 | new和delete实现原理 | 定位new表达式 | 内存泄漏
温馨提示:这篇文章已超过439天没有更新,请注意相关的内容是否还可用!
C/C++内存管理
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);
}
//1. 选择题:
//选项 : A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
//globalVar在哪里?____ staticGlobalVar在哪里?____
//staticVar在哪里?____ localVar在哪里?____
//num1 在哪里?____
//
//char2在哪里?____ * char2在哪里?___
//pChar3在哪里?____ * pChar3在哪里?____
//ptr1在哪里?____ * ptr1在哪里?____
//2. 填空题:
//sizeof(num1) = ____;
//sizeof(char2) = ____; strlen(char2) = ____;
//sizeof(pChar3) = ____; strlen(pChar3) = ____;
//sizeof(ptr1) = ____;
//3. sizeof 和 strlen 区别?
①对于内存区域理解
选择题组一
A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
- globalVar在哪里?
- staticGlobalVar在哪里?
- staticVar在哪里?
- localVar在哪里?
- num1 在哪里?
解析
-
int globalVar = 1;
globalVar是全局变量;“数据段,存储全局数据和静态数据”,故选C.数据段(静态区);
-
static int staticGlobalVar = 1;
staticGlobalVar是全局静态变量,“数据段,存储全局数据和静态数据。”故选C.数据段(静态区);
-
void Test() { static int staticVar = 1; }staticVar是局部静态变量,“数据段,存储全局数据和静态数据。”故选C.数据段(静态区);
-
void Test() { int localVar = 1; }localVar是局部静态变量,“栈,又叫做堆栈。非静态局部变量、函数参数、返回值等;栈是向下增长的。”故选A.栈;
-
void Test() { int num1[10] = { 1, 2, 3, 4 }; }num1是局部非静态变量,“栈,又叫做堆栈。非静态局部变量、函数参数、返回值等;栈是向下增长的。”故选A.栈;
选择题组二
A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)
- char2在哪里?
- *char2在哪里?
- pChar3在哪里?
- *pChar3在哪里?
- ptr1在哪里?
- *ptr1在哪里?
解析
-
void Test() { char char2[] = "abcd"; }char2是局部非静态变量,“栈,又叫做堆栈。非静态局部变量、函数参数、返回值等;栈是向下增长的。”故选A.栈;
-
void Test() { char char2[] = "abcd"; }数组是首元素的地址,所以对其解引用仍在栈。
-
void Test() { const char* pChar3 = "abcd"; }pchar3是地址,是局部非静态变量,注:const修饰的是字符串“abcd”为常量。“栈,又叫做堆栈。非静态局部变量、函数参数、返回值等;栈是向下增长的。”故选A.栈;
-
void Test() { const char* pChar3 = "abcd"; }pchar3是地址,指向一块存储字符串“abcd”的空间,*pchar3是对地址解引用,为字符串“abcd”。const修饰的是字符串“abcd”,所以为常量,“代码段,可执行的代码、只读常量。”故选D;
-
void Test() { int* ptr1 = (int*)malloc(sizeof(int) * 4); }ptr1是地址,是局部非静态变量,“栈,又叫做堆栈。非静态局部变量、函数参数、返回值等;栈是向下增长的。”故选A.栈;
-
void Test() { int* ptr1 = (int*)malloc(sizeof(int) * 4); }pchar3是地址,指向一块动态开辟的空间,“堆,用于程序运行时动态内存分配,堆是向上增长的。”故选B。
②对于sizeof以及strlen理解
填空题
- sizeof(num1) = ____;
- sizeof(char2) = ____;
- strlen(char2) = ____;
- sizeof(pChar3) = ____;
- strlen(pChar3) = ____;
- sizeof(ptr1) = ____;
解析
-
int globalVar = 1;
sizeof(num1):num1是开辟10个空间的数组,int为4字节;;
-
void Test() { char char2[] = "abcd"; }sizeof(char2) :“abcd”字符串中隐藏了'\0',有5个字符; -
void Test() { char char2[] = "abcd"; }strlen(char2) :strlen计算'\0'前面有几个字符,4个字符; -
void Test() { const char* pChar3 = "abcd"; }sizeof(pChar3):pchar3是地址,是地址就是4或者8; -
void Test() { const char* pChar3 = "abcd"; }strlen(pChar3) :strlen计算'\0'前面有几个字符,4个字符; -
void Test() { int* ptr1 = (int*)malloc(sizeof(int) * 4); }sizeof(ptr1):ptr1是地址,是地址就是4或者8;
③sizeof和strlen区别
【点击查看】sizeof和strlen的区别、sizeof(a)与sizeof(a+0)区别在哪里?sizeof(*a)、sizeof(a+1)、sizeof(a[1])...... | 笔试题分析| 超全
C++中动态内存管理
C语言内存管理方式在C++中可以继续使用,但是有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
new/delete操作内置类型
new/delete操作内置类型使用语法
- 申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[],注意要匹配起来使用。
数据类型 变量名 = new 数据类型; 数据类型 变量名 = new 数据类型(初始化值); 数据类型 变量名 = new 数据类型[个数]); delete 变量名; delete []变量名;
new/delete操作内置类型使用示范
void Test() { //动态申请一个int类型的空间 int* ptr4 = new int; //动态申请一个int类型的空间并初始化为10 int* ptr5 = new int(10); //动态申请三个int类型的空间 int* ptr6 = new int[3]; delete ptr4; delete ptr5; delete[] ptr6; }new/delete操作自定义类型
new/delete操作自定义类型语法
类名* 地址名 = new 类名[];
new/delete操作自定义类型使用示范
class A { private: int _a; public: A(int a = 0) :_a(a) { cout



