【内存】C/C++程序内存的分配

 

栈(stack)  :栈又称堆栈, 存放程序的  局部变量  (但不包括static声明的变量,  static  意味着  在数据段中  存放变量)。除此以外,在函数被调用时,栈用来传递参数和返回值。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。储动态内存分配,需要程序员手工分配,手工释放

 

堆(heap)  :堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)

 

BSS段:bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

数据段 :(data segment)通常是指用来存放程序中  已初始化  的  全局变量  的一块内存区域。数据段属于静态内存分配。 

 

代码段:(code segment/text segment)通常是指用来存放  程序执行代码  的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于  只读  , 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些  只读的常数变量  ,例如字符串常量等。程序段为程序代码在内存中的映射.一个程序可以在内存中多有个副本.

下图是APUE中的一个典型C内存空间分布图

 

 

 

https://blog.csdn.net/sunny04/article/details/40627311

rodata的意义同样明显,ro代表read only,即只读数据(const)。关于rodata类型的数据,要注意以下几点:
l         常量不一定就放在rodata里,有的立即数直接编码在指令里,存放在代码段(.text)中。
l         对于字符串常量,编译器会自动去掉重复的字符串,保证一个字符串在一个可执行文件(EXE/SO)中只存在一份拷贝。
l         rodata是在多个进程间是共享的,这可以提高空间利用率。
l         在有的嵌入式系统中,rodata放在ROM(如norflash)里,运行时直接读取ROM内存,无需要加载到RAM内存中。
l         在嵌入式linux系统中,通过一种叫作XIP(就地执行)的技术,也可以直接读取,而无需要加载到RAM内存中。

由此可见,把在运行过程中不会改变的数据设为rodata类型的,是有很多好处的:在多个进程间共享,可以大大提高空间利用率,甚至不占用RAM空间。同时由于rodata在只读的内存页面(page)中,是受保护的,任何试图对它的修改都会被及时发现,这可以帮助提高程序的稳定性 

 

注意代码段通常是只读,const int a 这样的常量是放在数据段。



#include<stdio.h>
#include<stdlib.h>
typedef struct
{
    unsigned char a;
    short b;
    short c: 5;
    short d: 7;
    short e: 6;
    long f;
    char **g;
    unsigned char h[5];
} MyStruct;
const MyStruct VarA = {0};
char *p = "test";
MyStruct VarB = {0};
int main()
{
    MyStruct *VarA;
    MyStruct VarB, VarC[3];
    const char *p1 = "test";
    VarA = (MyStruct *)malloc(sizeof(MyStruct));
    VarB.a = 12;
    printf("%d\n", sizeof(VarA));
    printf("%d\n", sizeof(VarB));
    printf("%d\n", ::VarB.a);
    return 0;
}

前面打两点表示是全局变量。

::VarA 放在ROM数据段

VarA放在栈中

*VarA 放在堆中

待完善

 

posted on 2022-10-04 01:25  bdy  阅读(16)  评论(0编辑  收藏  举报

导航