C/C++程序的内存分区

这篇具有很好参考价值的文章主要介绍了C/C++程序的内存分区。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


正确理解C/C++程序的内存分区,对程序员来说是最基本的要求。
网络上流形两大版本内存分区,分别为:
  1. 五大内存分区:堆、栈、全局/静态存储区、自由存储区和常量存储区。
  2. 五大内存分区:堆、栈、全局/静态存储区、字符串常量区和代码区。
    且不论以上两种分区孰是孰非,孰优孰劣,个人认为具体的内存分区和编译器有很大关系,不同编译器对内存的划分都不尽相同,但也大同小异。
    综合对比,查阅相关资料,提出个人对C/C++程序的内存分区的认识。可划分为四大内存分区:静态存储区代码区,即内存四区。

堆区

由开发人员手动申请,手动释放,若不手动释放,程序结束后由系统回收,生命周期是整个程序运行期间。使用malloc或者new进行堆的申请,堆的总大小为机器的虚拟内存的大小。
说明:new操作符本质上是使用了malloc进行内存的申请,new和malloc的区别如下:
(1)malloc是C语言中的函数,而new是C++中的操作符。
(2)malloc申请之后返回的类型是void*,而new返回的指针带有类型。
(3)malloc只负责内存的分配而不会调用类的构造函数,而new不仅会分配内存,而且会自动调用类的构造函数。

注:理解机器虚拟内存看:https://zhuanlan.zhihu.com/p/96098896
malloc 是 memory(内存)+ allocation(分配)两个英文拼凑的。读['mælɒk]

栈区

由系统进行内存的管理。主要存放函数的参数以及局部变量。
在函数完成执行,系统自行释放栈区内存,不需要用户管理。
整个程序的栈区的大小可以在编译器中由用户自行设定,VS中默认的栈区大小为1M,可通过VS手动更改栈的大小。
64bits的Linux默认栈大小为10MB,可通过ulimit -s临时修改。

静态存储区

静态存储区内的变量在程序编译阶段已经分配好内存空间(虚拟内存地址,在程序执行时会映射到对应的物理地址处)并初始化(在程序开始执行时,在main方法运行前,就已经就位了)。这块内存在程序的整个运行期间都存在,它主要存放静态变量、全局变量和常量。
注意:
(1)这里不区分初始化和未初始化的数据区,是因为静态存储区内的变量若不显示初始化,则编译器会自动以默认的方式进行初始化,即
静态存储区内不存在未初始化的变量。
(2)静态存储区内的常量分为常变量字符串常量(即字符串字面值),一经初始化,不可修改。常变量 分为编译期常变量和运行期常变量,区别是一个是在函数外定义的(存储在静态存储区),一个是在函数内定义的(存储在栈区),这里说的函数内定义的常变量只是用const一个限定词修饰的变量,如 const int a = 2。 如果是在函数内用static const 修饰变量,static在前,首先被它修饰的变量 首先是静态的,然后才是常变量,上面我们也说了静态变量是存储在静态存储区。
(3)字符串常量存储在静态存储区的常量区,字符串常量的名称即为它本身,属于常变量。这是说的就是 如 “abc”,“hello”,"中国人"的字符 串字面值。
(4)数据区的具体划分,有利于我们对于变量类型的理解。不同类型的变量存放的区域不同。后面将以实例代码说明这四种数据区中具体对应的变量。
(5)被const修饰的变量,可能存储在栈区,静态存储区,要看定义的地方。如果不涉及常量指针或指针常量 ,只是 如 const int a = 2;这种形式 ,是不允许修改 右值的。

代码区

代码区:存放程序编译后的二进制代码(存放二进制的机器指令),和 除字符串字面值外的其他类型的字面值都在代码区, 不可寻址(不可以寻址, 指的是不能通过&获得其地址),这里说的不可寻址是指的这些位于代码区的字面值不可寻址,而位于代码区的函数等都是可以寻址的。
int a = 0;//静态全局变量区
char *p1; //编译器默认初始化为NULL
void main()
{
    int b; //栈
    char s[] = "abc";//s在栈,"abc"在字符串常量区,尾部加\0,在函数体内执行到此处时,把"abc\0",从静态存储区拷贝一份数据到栈区,赋值给s.
    char *p2 = "abc";//字符串字面值123456存储在字符串常量区,尾部加\0(这里的字符串字面值会被优化后,在静态存储区只存一份),p2在栈上,在函数体内执行到此处时,把"abc\0",的首地址返给p2。现在的多数编译器都要求这种形式声明的字符串,前面加 const ,变成 const char *p2。防止修改静态存储区的字符串常量。而上面char s[] 操作修改的话,是修改自己栈里的那份数据,不是修改的静态存储区里的。
    static int c =0; //c在静态变量区,0为文字常量,在代码区
    const int d=0; //栈
    static const int d;//静态常量区
    p1 = (char *)malloc(10);//分配得来得10字节在堆区。
    strcpy(p1, "abc"); //123456放在字符串常量区,编译器可能会将它与p2所指向的"abc"优化成一个地方
}"abc" 被 加载到静态存储区时,是按照字符数组的方式存储在静态存储区的,会在其后面自动添加\0;
注:这里的"abc" 被优化后在静态存储区里只有一份。

总结

在理解C/C++内存分区时,常会碰到如下术语:数据区,堆,栈,静态存储区,静态区,常量区,常变量区,全局区,字符串常量区,静态常量区,静态变量区,文字常量区,代码区等等,初学者被搞得云里雾里。在这里,尝试捋清楚以上分区的关系。
数据区包括:堆,栈,静态存储区。
静态存储区包括:常量区(静态常量区),全局区(全局变量区)和静态变量区(静态区)。
常量区包括:字符串常量区和常变量区。
可以说,C/C++内存分区其实只有两个,即代码区(存放二进制的机器指令)和数据区。文章来源地址https://www.toymoban.com/news/detail-407823.html

到了这里,关于C/C++程序的内存分区的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL分区表的正确使用方法,适用场景,建立分区的条件

    什么是MySQL分区? MySQL分区是将一张表分割成独立的子表的技术。每个子表被称为分区,它们有着相同的结构和字段,但存储着不同的数据。这项技术可以提高查询速度,减少日志文件和磁盘空间的使用。 建立分区的条件 要建立MySQL分区,需要满足以下几个条件: 1.所需的

    2024年02月07日
    浏览(32)
  • 数据结构:动态内存分配+内存分区+宏+结构体

    1.定义一个学生结构体,包含结构体成员:身高,姓名,成绩;定义一个结构体数组有7个成员,要求终端输入结构体成员的值,根据学生成绩,进行冒泡排序。 1.申请一个10个int类型的堆区空间,并实现选择排序(需要导入头文件 #include stdlib.h) 2.用##拼接带参宏的参数 3.宏函

    2024年02月20日
    浏览(34)
  • C++内存分区模型

    在执行C++程序的过程中,内存大致分为四个区域: 栈区(Stack) :用于实现函数调用。由编译器自动分配释放,存放函数的参数值和局部变量等 堆区(Heap) :用于存放动态分配的变量。由程序员动态分配和释放,使用new和delete操作符 全局/静态存储区(Data Segment BSS Segment) :存放全

    2024年02月16日
    浏览(30)
  • 内存动态分区分配算法

    所谓动态分区分配,就是指 内存在初始时不会划分区域,而是会在进程装入时,根据所要装入的进程大小动态地对内存空间进行划分,以提高内存空间利用率,降低碎片的大小 动态分区分配算法有以下四种: 1. 首次适应算法(First Fit) 空闲分区以 地址递增的次序链接 。分

    2024年02月11日
    浏览(38)
  • 【JVM】内存分区

    程序在执行之前先要把java代码转换成字节码(class文件). JVM 首先需要把字节码通过类加载器(ClassLoader) 把文件加载到内存中 运行时数据区(Runtime Data Area) . 而字节码文件是 JVM 的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器 执行引

    2024年02月07日
    浏览(41)
  • 内存的五大分区

    一个由C/C++编译的程序占用的内存分为以下几个部分:栈区,堆区,全局区(静态区),文字常量区,代码区 在执行一个C/C++ 程序时,此程序拥有唯一的“内存四区”(栈区,堆区,全局区,代码区) 一个可执行程序在存储(没有调入内存时)分为代码区,静态区,文字常量

    2024年02月13日
    浏览(29)
  • 五大内存分区(笔记)

    一个由C/C++编译的程序占用的内存分为以下几个部分 : 堆区、栈区、全局区(静态区)、文字常量区、代码区 五部分。         在执行一个C/C++语言程序时,此程序将拥有 唯一 的“内存四区”——栈区、堆区、全局区、代码区。每个程序都有唯一的四个内存区域。    

    2024年02月15日
    浏览(27)
  • C++基础——内存分区模型

    C++程序在执行是,将内存大致分为4个区域: 代码区:用于存放二进制代码,由操作系统进行管理 全局区:存放全局变量和静态变量及常量 栈区:由编译器自动分配释放,存放函数的参数、局部变量等 堆区:程序员分配,如果程序员不释放,程序结束后由操作系统回收 内存

    2024年02月07日
    浏览(30)
  • 代码运行时内存分区

    计算机科学中,代码运行时的内存通常划分为以下分区: 堆栈 静态区 活跃区 代码段 常量存储区 全局/静态数据区 只读数据区 BSS 段 堆栈用于存储函数调用和局部变量。它是一个后进先出(LIFO)数据结构,这意味着最后进入堆栈的数据首先被弹出。 静态区存储全局变量和静

    2024年02月21日
    浏览(36)
  • c++内存的四大分区详解

    目录 前言: 1、程序的基本运行流程 2,为啥要分为四个区域? 3,分为哪四个区域? 4,4个区域详解 代码区: 为什么会设置这两个功能呢? 全局区: 栈区: 堆区:  new: 补充知识:new 总结: 这篇博客介绍 c++四大分区 的详解,其中也会涉及到有关 new 的知识

    2024年02月20日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包