(C++) 详解内存地址空间

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

详解内存空间

0. 概述

一个C/C++ 程序,编译之后,形成的程序,在执行期间,内存中不仅存在一块区域用于存放代码,还有一些其他的区域用于使用,本节会详解C/C++内部所使用的内存地址空间,关于各内存的作用、位置做一个整体概述。

1. C++ 内存布局

操作系统的内存布局可大致分为两块:内核态和用户态,此处的内核态和用户态,不同于操作系统在执行时所进入的内核态和用户态,此处专指内存。二者有类似之处,例如:只有操作系统处于内核态时才可以访问内核态内存,因此二者容易产生混淆。

仅需了解,此处指代:内存内核态 和 内存用户态。

内存内核态暂且不去深究,内存用户态在C++程序执行时,会划分成以下内容:

【栈、堆、全局/静态区、文字常量区、程序代码区】(地址从高到低)

2. 内存分区

(C++) 详解内存地址空间,c++,开发语言

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文章来源地址https://www.toymoban.com/news/detail-836888.html

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

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

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

相关文章

  • 【操作系统基础】【CPU访存原理】:寄存 缓存 内存 外存、内存空间分区、虚拟地址转换、虚拟地址的映射

    存储器怎么存储数据、内存空间分区、虚拟地址转换 计算机的存储器:寄存 缓存 内存 外存(按功能划分) 计算机的处理器需要一个存储器来存储大量的指令和数据以便自己不断取指执行和访问数据。 内存 (内存就是运行内存,如手机的8G运行内存,电脑的16G运行内存)就

    2024年01月25日
    浏览(59)
  • Linux内存管理 | 四、物理地址空间设计模型

    我的圈子: 高级工程师聚集地 我是董哥,高级嵌入式软件开发工程师,从事嵌入式Linux驱动开发和系统开发,曾就职于世界500强企业! 创作理念:专注分享高质量嵌入式文章,让大家读有所得! 前面几篇文章,主要讲解了虚拟内存空间的布局和管理,下面同步来聊聊物理内

    2024年02月08日
    浏览(52)
  • 【Linux】进程地址空间(带你认清内存的本质)

           🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️小林爱敲代码       🛰️博客专栏:✈️Linux之路       🛰️社区 :✈️ 进步学堂       🛰️欢迎关注:👍点赞🙌收藏✍️留言 我们在学习C语言的时候,应该都知道这

    2024年02月07日
    浏览(36)
  • C/C++|物联网开发入门+项目实战|函数输入与输出|值传递|地址传递|连续空间的传递|嵌入式C语言高级|C语言函数的使用-学习笔记(11)

    参考: 麦子学院-嵌入式C语言高级-C语言函数的使用 一堆代码的集合,用一个标签去描述它 复用化,降低冗余度 标签 ------ 函数名 函数和数组都属于内存空间,函数具备3要素: int *p; int a[100]; 1、函数名(地址) 2、输入参数 3、返回值 在定义函数时,必须将3要素告知编译器

    2023年04月20日
    浏览(55)
  • 【Linux-14】进程地址空间&虚拟空间&页表——原理&知识点详解

    前言 大家好吖,欢迎来到 YY 滴 系列 ,热烈欢迎! 本章主要内容面向接触过Linux的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《初学者易

    2024年04月29日
    浏览(51)
  • C++中的内存空间管理详解【C++】

    如图代码中变量在内存中的存储位置。 内存分布图: 1. 栈又叫做堆栈,存储非静态局部变量/函数参数/返回值等等,栈是向下增长的。 栈是向下增长的,而堆是向上增长的? 一般来说,在栈上开辟空间,先开辟的空间地址较高,而在堆开辟空间,先开辟的空间地址较低。

    2024年02月07日
    浏览(36)
  • 【初识c语言】地址及其内存的简介

    晚钟悠然追为你 回声两度为你作答 暗夜逆流而上 树根在秘密发电 你的果园亮了 我径直走向你 带领所有他乡之路 当火焰试穿大雪 日落封存帝国 大地之书翻到此刻 ————节选 北岛《路歌》 一. 内存的简介: 在计算机的组成结构中,有一个很重要的部分,就是 储存器 。

    2024年02月02日
    浏览(40)
  • [C语言][数据结构][动态内存空间的开辟]顺序表的实现!

    目录 零.必备知识 a.顺序表的底层是数组. b.数组在内存中是连续存放的. c.动态内存空间的开辟(malloc,calloc,realloc). 一.顺序表的定义与实现          1.1 顺序表的定义          1.2 顺序表的初始化          1.3 顺序表的销毁          1.4 顺序表容量的检查与调整

    2024年04月09日
    浏览(88)
  • 【Linux】详解线程控制 -- 线程用法 | 线程等待 | 线程ID及地址空间布局

    (关于 用户 → 库 → OS :具体可看下面线程地址空间布局) 这个 clone 我们不用,这是OS提供给第三方库所用的接口 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“ pthread_ ”开头的,要使用这些函数库,要通过引入头文 pthread.h ,链接这些线程函数库时要

    2024年02月15日
    浏览(56)
  • C语言-详解内存函数

    它的函数原型如下: 具体的函数介绍如下: 好,相信同学们看了这个函数,应该是能够简单了解函数中各个参数的用法。 下面我们来总结一下: 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 指向的内存位置。 这个函数在遇到 \\\'\\0\\\' 的时候并不会停下来。

    2024年04月16日
    浏览(53)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包