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++内存分布内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!