【内存】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 放在堆中
待完善