💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍
文章目录
前言:
通过文章,我们主要学习在C++\C 中,各个对象,变量,实参等,以及Static修饰的函数或变量的存储位置。 并通过例题来详细讲解。
一、C++;内存的五大分区
- 栈区、 堆区、内存映射段、静态区/数据段、代码段
🔸内核空间 :这个区域是系统内部的区域,我们是不可编辑的;
🔸栈区 :(主要存储函数运行时而分配的局部变量,函数参数,返回数据,返回地址,指针
,const局部变量
)
🔸内存映射段 :是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信
🔸堆区 :由程序员可以自行分配的一块空间。如malloc、new。
🔸 数据段 :存储全局变量,静态变量.例如:sattic修饰的静态变量。数据段又分BSS
段和DATA
段 。
其中BSS存放的是程序员编写的未初始化的全局变量和静态变量(这其中C和C++的BSS还有区别,区别就是:C中的BSS段分为高地址和低地址,高地址是存放全局变量,低地址是存放静态未初始化);
DATA存放已经初始化的全局变量、静态变量和常量。
🔸代码段 :又被称为文本段
。主要存储程序指令、代码
、只读常量
。代码段中存放函数
(类的成员函数和全局函数)的二进制代码,并且这个区域是只读
区域;
二、栈区和堆区详解
1、栈区
栈区向地址减小的方向增长
- 在执行函数时,函数内部变量的存储在栈上。函数执行结束时,系统自动回收。
- 栈区:大小大约只有2MB。分配容量有限
- 执行效率很高:栈内存分配运算内置于处理器的指令集中。
2、堆区
堆区向地址增大的方向增长
- 这个区域是在
运行时
使用的,由程序员
分配和释放内存,程序结束时操作系统会对其进行回收,(程序员分配内存像malloc、free、new、delete)都是在这个区域进行的; - 产生内存碎片:频繁的new/delete会造成内存空间不连续,产生大量碎片,使程序效率降低。栈不会产生碎片,因为栈是先进后出的队列。
- 空间大:一般来说,对于32位系统下,堆内存空间可以达到4G(2的32次方).从这个角度来看堆的空间是非常大的
- 堆的效率很低:堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
3.⛔️【注意】
无论堆栈都要防止产生越界,因为越界的结果很严重,要么程序崩溃,要么程序的堆栈结构被破坏,产生意想不到的结果。
三、指针的存储位置
在C++中,指针变量存放在内存的栈区
。栈区是一块连续的内存空间,用于存储局部变量和函数调用时的参数。当我们声明一个指针变量时,它会被分配在栈区,并且占用固定大小的内存空间。
指针变量存放在栈区中
,而指针所指向的对象或者内存地址则可以位于栈区、堆区或者全局/静态存储区。当我们使用指针来引用一个对象时,指针会保存该对象的内存地址。
需要注意的是,指针变量本身的值(即存放的地址)是存放在栈区的,而指针所指向的对象或者内存地址所对应的数据则可能位于其他不同的内存区域。
四、例题巩固
下面是考察C++内存的一道经典例题。
cpp
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在哪里?____
解答:
1.globalVar在哪里?____
答:C数据段
。globalVar定义在全局,是一个全局变量。
2.staticGlobalVar在哪里?____
答:C.数据段
。该变量是static修饰的静态变量,存储于静态区。
3.staticVar在哪里?____
答:C.数据段
。该变量虽然处于函数体内,但是它是static修饰的静态变量,仍然存储于静态区。
4.localVar在哪里?____
答:A.栈
。该变量是一个普通的成员函数局部变量,存储于栈区。
5.num1 在哪里?____
答:A.栈
。该数组是属于普通的函数内的局部变量,依然存储在栈区。
6.🚩char2在哪里?____
答:A.栈
。char2是数组名。该数组是属于普通的函数内的局部变量,依然存储在栈区。
7.🚩*char2在哪里?___
答:A.栈
。*char2来说,很多同学就会认为它是在【常量区】中,实际上,数组名本身就是一个指针,指向这个字符串的首地址
。那我们对首元素地址
去进行解引用
的话就拿到了首字符的地址
,那么这也只是一个字符而已,并不是一个字符串,所以还是存放在【栈区】中的
8.pChar3在哪里?____
答:A.栈
。pChar3:是一个指针。指针存储在栈区。
9.*pChar3在哪里?____
答:D.代码段(常量区)
。第八题说过pChar3是一个指针,指向一串字符, 该字符存储于常量区,也就是代码段。
10.ptr1在哪里?____
答:A。栈
。ptr1仍然是一个指针,存在栈区。
11 . *ptr1在哪里?____
答:B.堆
。pttr1指向一块区域 ,对这块区域仅用也就是动态开辟的空间,存储在堆区。