linux C 进程内部存储管理
一方面能足够强健的承受。另一方面又能保持清醒的品质,正是一个拥有一颗完善不可战胜的灵魂的标志
----------马克.奥勒留
之所以写上面这句话是看的一些鸟书,每章前面有有那么一句名言貌似引导该章的思想。我也效仿,上句摘自沉思录卷一目录。当然上句纯属装B,与以下内容无关,本来我计划写进程控制,及通讯,想想还是从0开始来。也就是后所下一篇就是进程的控制了。
一 谈到内存,首先想到的是数据存储,多字节存储分为大端小端,大端就是数据中的最低位存数存储在内存中的最高位,小端是数据中的最低位存储在内存中的最低位,其实我们的用的pc都是intel的X86都是小端存储,ARM一般是大端大端存储,我们来写个小程序来看看你的电脑时大端还是小段,以后给开发板板写的时候也可看看他的内存存储方式。
1 #include<stdio.h> 2 3 int mian() 4 5 { 6 7 int a = 0x12345678; 8 9 char *p; 10 11 p = (char *) &a; 12 13 if (*p == 0x78) 14 15 { 16 17 printf(" 这是小端。。。。\n"); 18 19 } 20 21 else 22 23 printf("这是大端。。。。\n"); 24 25 return 0; 26 27 }
二 : C程序内存分布分为 代码段 数据段 栈和堆 常量存储
代码段就是cpu执行的指令。当你打开多个一个程序的多个窗口,例如打开多个shell,他们使用的是同一个代码段,其他的数据段不同。
数据段和缓冲段: 初始化的数据段(.data)就是数据段,它包括明确给定初值的全局变量和静态变量。如int a = 10; (全局变量);static int b = 5;
编译的时候该段的大小时不会改变的,还有就是这个段的内容就直接在内存中,不在外存上。
非初始化的数据段(.bss):在这个段上的内容是没有给初值的全局变量,如int max; 这段内容是存在外存上的。表达的不是很请,代码最具有说服力。
#include<stdio.h> int a[30] int main { printf ("hello world \n"); return 0; }
这里有全局变量a[30],int 占四个字节,int a[30] 应该占120字节,如果注释掉int a[30]变量,两个程序的大小应该相差120字节,可是事实上只差18字节,所以.bss并不是程序的一部分,保存在外存中。多的18个字节是系统标记。bss段的内容和属性。这里没有把具体结果贴出来,有兴趣可以编译完后看看他们的二进制文件的大小。
三 栈 : 所有自动变量以及函数调用时所要保存的信息,都储存在栈上。*每次调用时栈会随着函数的调用而增长,随着函数调用结束而消亡。所以我们要避免将一个指向局部变量的指针作为函数返回。因为调用完就变量就释放了,返回不来了。
自动变变量有3中存储方式:1存储在数据段或bss端(静态局部变量)。2存储在寄存器中(寄存器变量)。3存储在栈中(一般自动变量)。自动变量的作用域往往只在函数中。
四 堆 :堆用于存储用户申请的存储空间。在堆中进行动态内存分配。 int * p = (int *)malloc(sizeof(int));这里给大家补充个小知识 “*”的两个作用。一个就是大家常用的是地址解析,就是指针。第二个就是如int *p = &a;*的作用是告诉编译器p将存储一个整型的的地址。上面p是指向分配内存的首地址。其实动态分配内存有三个函数
malloc calloc realloc具体可以google。要是再说详细就跑题了。最常用的的还是malloc.
五 常量的存储:常量分为简单的,和复杂的。如123,‘a’,复杂的如'yaoze studying...',简单的就随指令一起存储,这样可以提高程序的运行速度,长的字符串不会存储在代码段,这样会导致代码段变大。所以复杂常量,编译器会将存储的首地址转换成一个简单的变量随指令存储,把复杂的常量存储在特殊的内存段中叫.rodata.
这基本上差不多就介绍完了,由于是处女作,有错请探讨。。。。。。
ps : 接下来会一个持续更新,有关linux , C 的一些东西。下集预告:进程控制。