有没有做机械加工的网站,成都网站建设公司官网,咖啡商城网页设计代码模板,wordpress 更换路径详解内存空间
0. 概述
一个C/C 程序#xff0c;编译之后#xff0c;形成的程序#xff0c;在执行期间#xff0c;内存中不仅存在一块区域用于存放代码#xff0c;还有一些其他的区域用于使用#xff0c;本节会详解C/C内部所使用的内存地址空间#xff0c;关于各内存的…详解内存空间
0. 概述
一个C/C 程序编译之后形成的程序在执行期间内存中不仅存在一块区域用于存放代码还有一些其他的区域用于使用本节会详解C/C内部所使用的内存地址空间关于各内存的作用、位置做一个整体概述。
1. C 内存布局
操作系统的内存布局可大致分为两块内核态和用户态此处的内核态和用户态不同于操作系统在执行时所进入的内核态和用户态此处专指内存。二者有类似之处例如只有操作系统处于内核态时才可以访问内核态内存因此二者容易产生混淆。
仅需了解此处指代内存内核态 和 内存用户态。
内存内核态暂且不去深究内存用户态在C程序执行时会划分成以下内容
【栈、堆、全局/静态区、文字常量区、程序代码区】地址从高到低
2. 内存分区 3. 栈区
栈用于存放局部变量、函数参数、函数调用返回值、函数调用返回地址等数据程序从main 主函数开始运行到主函数运行结束在此之间调用其他函数可看作将其他函数进行压栈的一个过程在栈区内的变量、地址等当该函数执行结束后其中的资源由系统自动释放。如main 函数中调用 func 函数func 函数内生成一个数据将其作为返回值进行返回。main 函数中使用变量进行接收打印可以看出打印值不同于 func 函数中的值未定义行为当func 返回后该函数出栈其中的资源被系统释放。
示例如下
char *func() {char buf[] hello world;return buf;
}
int main(int argc, char *argv[]) {char *buf func();cout buf buf endl;return 0;
}另外值得注意的一点是栈区的使用操作方式类似于数据结构中的栈即在使用时后进先出函数调用机制使用栈区完成大量频繁的调用栈区务必会造成时间资源的消耗导致程序的执行效率下降。C 语言解决方法是使用宏代替短小频繁的函数体C 语言的解决方法是使用内联函数进行替换还需提高编程技巧。
机器在栈上申请的空间有限因此在栈上使用的内存需要注意大小。
4. 堆区
堆位于栈区下全局/静态区上栈区向下生长堆区向上生长因此日常提到堆栈是因为这两者的内存空间十分接近。
堆区是程序员可手动分配的内存空间特点是需要手动申请和手动释放在C语言中使用 malloc 和 free 进行申请和释放。C中则使用 new 和 delete 进行申请和释放此处不再赘述 malloc/free 和 new/delete 的区别若感兴趣请自行查询相关资料。
堆区申请的数据在程序执行阶段不会被系统所自动释放因此C和C程序员需要注意内存大小内存释放问题。程序结束时会被操作系统回收
需要注意
1.申请堆内存之后立刻验证内存空间是否申请成功。
2.申请行为必须对应释放行为有申请内存则必有释放行为因此写 malloc 之后立刻写上free语句。new/delete 同理。
3.free 和 delete 虽然传入的是指针但释放的确是内存空间因此需要将该指针置为null防止野指针问题。
另外堆的运行速度、效率不及栈且存在内存碎片问题。 使用 malloc 和 free 时需要添加头文件。
5. 全局/静态区
全局区、静态区是一片区域原因在于全局变量和静态变量的内存地址都位于这片空间下。该空间位于堆下低地址。
定义一个变量时需要及时进行初始化变量被定义 static 之后只有当前模块可见。当一个局部变量被定义为 static时虽然该局部变量的可见范围仍然属于该函数但该局部变量的生命周期已经延长到了程序生存期。
6. 文字常量区只读
文字常量区用于定义常量字符串程序结束后由系统进行释放不可进行写操作。
const char* 定义文字常量后直接使用字符串二者处于的地址相同都位于文字常量区。
#include func.h#include iostream
using std::cout;
using std::endl;int main(int argc, char *argv[]) {const char *str Hello world;printf(str address %p\n, str);printf(hw address %p\n,Hello world);return 0;// str address 0x561f4d567004// hw address 0x561f4d567004
}局部的常量字符串放在栈或者文字常量区视编译器而定。
7. 程序代码区只读
顾名思义存放程序代码的位置函数也是存放在某个内存地址的比如可以打印看一下main函数的运行地址。
#include iostream
using std::cout;
using std::endl;int main(int argc, char *argv[]) {printf(main address %p\n, main);return 0;
}参考https://www.cnblogs.com/songdanzju/p/7422507.html