亲宝软件园·资讯

展开

C++内存分布

CJL爱吃鱼 人气:0

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        // 栈区

代码区

就是代码存放的地方。

下面用一张图片总结:

加载全部内容

相关教程
猜你喜欢
用户评论