1.可执行文件存储时被划分为哪几个区域
可执行文件就是还没有载入内存,还没有开始运行的程序,分为:代码区、数据区、未初始化数据区。
代码区:存放CPU执行的机器指令。代码区是可共享的,另外的程序也可以调用他,因为如果有一段代码被频繁的执行,那么内存里只要存一份代码就可以了。
数据区(全局初始化区/静态数据区):该区包含了在程序中被初始化的全局变量、静态变量和常量。
未初始化数据区:存入的是全局未初始化变量,也叫bbs区。
2.正在运行的程序被划分为哪几个区域
正在运行的程序被划分为代码区、初始化数据区、未初始化数据区、堆区和栈区。
代码区:也叫代码段,指程序执行时用来存放代码的一块内存区域。这部分内存的大小在程序运行前就已经确定了。代码区中包括操作码和要操作的对象,如果是具体的数字比如10,就直接存放在代码区里,如果是局部变量就会在栈里分配内存空间,引用该地址,如果是bbs区或数据区,在代码区中同样引用该数据地址。
数据区:数据区里存放的是已经初始化的全局变量,静态变量和常量。
未初始化区域:存放未初始化变量的一块内存区域,在程序开始运行的时候改变他的值。
栈区:存放函数参数、局部变量、以及在任务切换时存放当前任务的上下文,由编译器自动分配和释放。
堆区:用于动态内存分配,当调用malloc方法分配内存时,新分配的内存就会被添加到堆上。当使用free方法释放内存时,被释放的内存从堆里被去除。程序运行时,堆里的内存需要程序员手动管理,显示的声明和释放。
3.栈溢出
程序执行的时候有一个局部变量,编译器会为该局部变量在栈里开辟一段内存区域,如果需要申请的内存空间大于栈内剩余的内存空间,栈溢出。
4.堆内存的分配过程
在c语言中使用malloc函数,在c++中使用new函数就会申请堆中的内存空间。分配内存空间时,要遍历记录空闲内存地址的链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从记录空闲内存地址的链表中删除,然后把这段堆空间分配给程序。
5.静态分配和动态分配
在c语言中,有两种为对象分配内存空间的方式:静态分配和动态分配。
静态分配是在编译过程中在程序执行之前分配的,动态分配是在程序执行的过程中动态的分配。
静态分配的对象是有名字的,可以直接对其进行操作。
动态分配的对象是没有名字的,是一段内存地址,需要通过指针间接进行访问。
静态对象的分配与释放由编译器自动处理,动态分配的对象由程序员手动分配与释放。
6.堆和栈的区别
🌟栈内存由编译器自动分配和释放,不需要手动管理。
🌟堆内存由程序员手动分配和释放,需要手动管理,容易造成内存泄漏。
🌛栈空间一般比堆空间要小。
🌛栈是一块连续的内存区域,栈顶的地址和栈的大小是设定好的,当申请的空间大于栈的剩余空间会造成栈溢出,用户能够从栈获得的空间较小。
🌛堆是不连续的内存区域,由低地址向高地址扩张。系统用链表存储空闲内存地址,因此堆更加灵活。
☀️堆空间频繁的进行malloc和free或者new和delete操作容易产生内存碎片,使程序的执行效率降低。
☀️栈空间严格的遵守先进后出的执行顺序,从栈顶插入从栈顶弹出,不会产生碎片问题。
🌍堆从低地址向高地址扩张,栈从高地址向低地址扩张。
🔥栈的执行效率要高于堆。
7.char* a与char a[]的区别
char* a = "hello";
hello是一个字符串常量,存储在数据区,指针a指向字符串hello的第一个字符,通过指针只能访问字符串常量但是不能改变他。
在编译时刻就已经赋值。
char a[] = "hello";
hello此时放在栈区,可以通过指针a去访问和改变他。
在运行时才赋值,虽然没有指明数组的长度,但是系统开辟的长度就是6,结尾有一个'\0'
网友评论