C++浅析程序中内存的分布

 更新时间:2022年08月15日 16:42:33   作者:CJL爱吃鱼  
这篇文章主要介绍了C++内存分布及用法,从内存的基础概念到内存分配进行了讲解,内存是我们开发中最重要的一部分,往往逻辑上的错误就会造成内存泄漏,导致程序无法运行,下面我们就来了解文章对该内容的详细介绍

C++之程序的内存分布

最近在复习C++相关的知识,整理一下。

C++的存储区主要有以下几类:

栈区:就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

堆区:就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉, 那么在程序结束后,操作系统会自动回收。只new不delete会造成内存泄漏。

全局/静态存储区:全局变量和静态变量(static修饰的变量)是存储在同一块内存区域的。以前C语言还区分初始化的和未初始化的全局变量,将这两类分别存储在不同的区域,现在在C++里这两者已经不做区分了。

常量存储区:就是常量字符串或者const修饰的变量,该区域的变量不允许修改。

代码区(text):存放程序代码块的地方。

这里通过一个例子来分别看一看这些不同区域的变量。

栈区

    int bb = 1;              // 栈区变量 stack
    char s[] = "abc";       // 栈地址变量
    int *p2 = NULL;         // 栈地址变量

将以上变量的地址分别打印

(lldb) p &bb
(int *) $0 = 0x00000003040cf224
(lldb) p &s
(char (*)[4]) $1 = 0x00000003040cf220
(lldb) p &p2
(int **) $2 = 0x00000003040cf218
(lldb) 

可以看到这几个存储在栈区的变量是挨着存储,且地址依次从高到低变化。

堆区:

    int *ph = new int(10);       // ph在栈区,指向堆(heap)区变量 (地址增长)
    int *ph2 = new int(20);      // 堆(heap)区变量

分别打印指针的地址和指针指向的地址的值

(lldb) p &ph
(int **) $0 = 0x00000003040cf1f0   // 指针的地址,在栈区
(lldb) p &ph2
(int **) $1 = 0x00000003040cf1e8    // 指针的地址,在栈区
(lldb) p ph
(int *) $2 = 0x0000000108e20db0        // 指针指向的地址,在堆区
(lldb) p ph2
(int *) $3 = 0x0000000108e20900        // 指针指向的地址,在堆区

从上面的例子可以看到,指针本身存储在栈区,其地址相邻且从高到低变化。

指针指向的地址在另一块区域,该区域称为堆区,该区域的地址是从低到高变化的。但是并不具有相邻的特点。

全局/静态存储区

int globleA = 0;        // 全局初始化区
int *pPoint;               // 全局未初始化区 默认为0,指针为NULL
int main(int argc, const char * argv[]) {
    static int c = 0;       // 全局(静态)初始化区 (和全局变量是一样的)
   	return 0;
}

打印出地址和结果:

(lldb) p &globleA
(int *) $0 = 0x00000001000080d8            // 全局/静态变量区
(lldb) p &pPoint
(int **) $1 = 0x00000001000080e0        // 全局/静态变量区
(lldb) p &c
(int *) $2 = 0x00000001000080d4        // 全局静态变量区
(lldb) p pPoint
(int *) $3 = 0x0000000000000000        // 未初始化的值为NULL

常量区

char *p3 = "123456";    // p3在栈区,但是它指向的变量在常量区(无法改变), 指针可以跨区域访问

(lldb) p p3
(char *) $3 = 0x0000000100003f43 "123456"  // 常量区
(lldb) p &p3
(char **) $4 = 0x00000003040cf210        // 栈区

代码区

就是代码存放的地方。

下面用一张图片总结:

到此这篇关于C++浅析程序中内存的分布的文章就介绍到这了,更多相关C++内存分布内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c/c++ 利用sscanf进行数据拆分操作

    c/c++ 利用sscanf进行数据拆分操作

    这篇文章主要介绍了c/c++ 利用sscanf进行数据拆分操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C++你可能不知道地方小结

    C++你可能不知道地方小结

    c++中编译器替我们完成了许多事情,我们可能不知道,但也可能习以为常
    2013-01-01
  • C++遍历某个文件夹下面的子文件夹及其所有文件

    C++遍历某个文件夹下面的子文件夹及其所有文件

    这篇文章主要介绍了C++获取某个文件夹下面的子文件夹及其所有文件,需要的朋友可以参考下
    2021-07-07
  • C++ Qt实现音视频播放功能

    C++ Qt实现音视频播放功能

    Qt版本 5.9 基于C++11 Qt核心组件与附加组件安装时请打钩 否则可能出现项目中缺少视频播放模块的问题,由于最近着手的Qt项目需要视频播放自己做的时候踩很多坑避免以后踩坑,故在此记录实现过程,感谢的朋友参考下吧
    2021-11-11
  • 详细分析C++ 数据封装和数据抽象

    详细分析C++ 数据封装和数据抽象

    这篇文章主要介绍了C++ 数据封装和数据抽象的的相关资料,文中代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • FFmpeg获取网络摄像头数据解码

    FFmpeg获取网络摄像头数据解码

    这篇文章主要为大家详细介绍了FFmpeg获取网络摄像头数据解码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • 详解_beginthreadex()创建线程

    详解_beginthreadex()创建线程

    这篇文章主要介绍了详解_beginthreadex()创建线程,使用_beginthreadex(),需要的头文件支持#include <process.h> 下面我们就来看看具体的实现吧
    2022-01-01
  • C++之openFrameworks框架介绍

    C++之openFrameworks框架介绍

    本章我们将介绍一个非常好用的跨平台的 C++开源框架 openFrameworks。它是一个开源的跨平台的C++工具包,方便开发者创建出一个更简单和直观的框架,擅长开发图像和动画,感兴趣的同学可以参考一下
    2023-05-05
  • 一文解析C语言中动态内存管理

    一文解析C语言中动态内存管理

    这篇文章主要为大家详细介绍了C语言中动态内存管理的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以跟随小编一起学习一下
    2024-02-02
  • QString使用正则操作的接口实现

    QString使用正则操作的接口实现

    这篇文章主要介绍了QString使用正则操作的接口实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12

最新评论