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语言常见图片格式判断实例

    这篇文章介绍了c语言常见图片格式判断实例,有需要的朋友可以参考一下
    2013-09-09
  • C语言模拟实现库函数详解

    C语言模拟实现库函数详解

    C语言库函数是把自定义函数放到库里,是别人把一些常用到的函数编完放到一个文件里,供程序员使用,下面让我们一起来详细了解它
    2022-07-07
  • 使用C++17实现JSON库设计思路示例全解

    使用C++17实现JSON库设计思路示例全解

    这篇文章主要为大家介绍了使用C++17实现JSON库设计思路示例全解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 介绍C语言中tolower函数的实例

    介绍C语言中tolower函数的实例

    这篇文章主要介绍了介绍C语言中tolower函数的实例,本文列出了该函数的头文件,功能说明等,以及如何使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++操作MySQL的实现示例

    C++操作MySQL的实现示例

    这篇文章主要介绍了C++操作MySQL的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • C语言数据结构与算法时间空间复杂度基础实践

    C语言数据结构与算法时间空间复杂度基础实践

    这篇文章主要为大家介绍了C语言数据结构与算法中时间空间复杂度的基础实践,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • C++中Overload,Override,Hide之间的区别

    C++中Overload,Override,Hide之间的区别

    重载overload,这个概念是大家熟知的。在同一可访问区内被声名的几个具有不同参数列的(参数的类型、个数、顺序不同)同名函数,程序会根据不同的参数列来确定具体调用哪个函数,这种机制就是重载
    2013-09-09
  • C++实现词法分析器

    C++实现词法分析器

    这篇文章主要为大家详细介绍了C++实现词法分析器的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 详解C++编程中类模板的相关使用知识

    详解C++编程中类模板的相关使用知识

    这篇文章主要介绍了详解C++编程中类模板的相关使用知识,包括函数的参数类型替换等方法,需要的朋友可以参考下
    2015-09-09
  • C++中4种强制类型转换的区别总结

    C++中4种强制类型转换的区别总结

    C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。下面这篇文章主要给大家介绍了C++中4种强制类型转换的区别,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12

最新评论