1. RAM内存 
         RAM内存包括:代码段(text)、数据段(data)、bss段、堆栈段(head stack) 

 

 2. 编译器编译结果分析


      编译结果有代码段(text)、数据段(data)、bss段。

代码段(.text)是可执行指令的集合;
数据段 (.data) 表示已经初始化不为0的存放在静态区的数据(全局 or静态)。
.bss段 表示未初始化的或为0的存放在静态区的数据(全局 or静态)。
       从可执行程序的角度来说,如果一个数据未被初始化,就不需要为其分配空间,所以.data 和.bss 的区别就是 .bss 并不占用可执行文件的大小,仅仅记录需要用多少空间来存储这些未初始化的数据,而不分配实际空间。所以......

       代码段(text)、数据段(data)这两者相加共同构成可执行文件的大小,dec也就是文件大小(hex也是文件大小,只不过是16进制表示的)。

3. 堆栈
3.1 堆
堆保存函数内部动态分配(malloc 或 new)的内存,是另外一种用来保存程序信息的数据结构。
堆是先进先出(FIFO)数据结构。堆的地址空间是向上增加,即当堆上保存的数据越多,堆的地址越高。动态内存分配。
注意:堆内存需要程序员手动管理内存,通常适用于较大的内存分配,如频繁的分配较小的内存,容易导致内存碎片化。

3.2 栈
栈保存函数的局部变量(不包括 static 修饰的变量),参数以及返回值。是一种后进先出(LIFO)的数据结构。
在调用函数或过程后,系统会清除栈上保存的局部变量、函数调用信息及其他信息。
栈的另外一个重要特征是,它的地址空间 向下减少,即当栈上保存的数据越多,栈的地址越低。静态内存分配。
注意:由于栈的空间通常比较小,一般 linux 程序只有几 M,故局部变量,函数入参应该避免出现超大栈内存使用,比如超大结构体,数组等,避免出现 stack overflow。

5.例子

#include <iostream>
using namespace std;
 
int a = 0;//初始化的全局变量:保存在数据段
char *p1;//未初始化的全局变量:保存在BSS段
 
int main()
{
    int b;//未初始化的局部变量:保存在栈上
    char s[] = "abc";//"abc"为字符串常量保存在常量区;数组保存在栈上,
    并将常量区的"abc\0"复制到该数组中。这个数组可以随意修改而不会有任何隐患,
    而"123"这个字符串依然会保留在静态区中。
 
    char *p2;//p2保存在栈上
    char *p3 = "123456";//p3保存在栈上,"123456\0"保存在data区的read-only部分
    //注意:如果令p3[1] = 9; 则程序崩溃,指针可以访问但不允许改变常量区的内容
    //声明了一个指针p3并指向"123456\0"在静态区中的地址,事实上,p3应该声明为
    char const *,以免可以通过p3[i]='\n'这一类的语法去修改这个字符串的内容。如果这样
    做了,在支持“常量区”的系统中可能会导致异常,在“合并相同字符串”的编译方法下会导致其它
    地方的字符串常量古怪地发生变化。
 
    static int c = 0;//初始化的静态局部变量:保存在数据区(数据段)
 
    p1 = (char *)malloc(sizeof(char) * 10);//分配的10字节区域保存在堆上
    p2 = (char *)malloc(sizeof(char) * 20);//分配的20字节区域保存在堆上
 
    strcpy(p1, "123456");
    //"123456\0"放在常量区,编译器可能会将它与p3所指向"123456"优化成一个地方
 
    return 0;
}

————————————————

 

                            By——口袋里のInit
                        
原文链接:https://blog.csdn.net/wangguchao/article/details/119776738

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐