linux进程内存管理

来源:互联网 发布:seo工程师认证 编辑:程序博客网 时间:2024/05/16 06:06

  1.数据的内部存储 嵌入式开发培训

  大端:起始地址存放数据的高位

  小端:起始地址存放数据的低位

  大端小端是由处理器的体系结构决定的,不是操作系统。

  测试方法:

  #include

  int main()

  {

  int a=0x12345678;

  char *p=NULL;

  p=&a;

  if(*p = 0x12)

  printf("big endian.\n");

  else

  printf("little endian.\n");

  return 0;

  }

  2.C程序的存储布局--代码段

  代码段是用于存放CPU要执行的指令段。代码段只读,任何对代码段的修改,都会造成段错误。一个程序在多数情况下是不需要修改自身代码的,只有一种情况例外,嵌入式开发培训就是一些长时间运行的升级程序。可以采用共享库的形式,来修改一个运行中的程序的代码段。

  3.C程序的存储布局--数据段和缓冲段

  初始化数据段(。data):也称为数据段。包含初始过的全局变量和静态变量。该段的大小在编译时确定。未初始化数据段(。bss,block start with symbol):这个段中的数据是程序没有明确初始化的静态变量+全局变量。又叫做块缓存段,块存储段在elf格式的目标文件中,bss段并不占用实际的空间,嵌入式开发培训而只是一个占位符,已告知指定位置上应当预留全局数据的空间。块缓存段存在的原因是为了提供磁盘上存储空间的利用率。

  未初始化数据段不会存储在外存上,在程序运行时,由内核将段中的数据初始化成0或NULL。

  4.C程序的存储布局--栈

  所有的自动变量+函数调用时所需要保存的信息(返回地址,函数调用前各寄存器的值)都保存在栈中。

  每个函数都有对应的栈帧。嵌入式开发培训栈帧在一个函数调用时被创建,在函数调用结束时消亡。所有的函数都是基于进程的栈创建的,从全局的角度来看,一个进程只有一个栈(也只有一个堆),但每个函数执行时,都对应一块独立的栈帧。所以不应该在栈帧上传递一个返回值的地址,因为函数调用结束后,该栈帧有可能会被覆盖掉,相应的,对该地址的引用就会是无效的。

  注意:不应该将一个指向局部变量的指针作为返回值返回。在linux环境下,这种方法是错误的。但Windows平台下,似乎是可行的。

  函数调用结束后,嵌入式开发培训栈帧上的内容还存在,函数返回的是一个局部变量的地址。如果该栈帧被其他函数覆盖,对该指针的引用也就失效了。

  5.C程序的存储布局--堆

  堆,用于存储用户申请的内存空间,系统通常在堆中进行动态内存分配。

  对于小端处理器,栈地址由高-->低,堆地址由低-->高增长。大端处理器正好相反。

  6.常量的存储

  C语言中常量有两种:简单常量,如1234,‘c;复杂常量,如iloveyou等字符串常量。

  在汇编语言中,对于常量参与运算的C语句,如a+1的汇编代码被汇编成如下:

  mov r1, a

  add r1, 1

  简单常量,它随着指令一起存储,也就是说简单变量存储在程序的代码段里。

  对于复杂常量,长度不定,放在代码段里面是不明智的,嵌入式开发培训因此编译器将其存储在一个特殊的数据段,将其存储的首地址转换成一个简单变量随着指令存储。这个段叫做。rodata段。

  7.动态内存管理

  C语言中只能通过malloc和其他派生函数动态申请内存,malloc作为一个库函数,嵌入式开发培训它的linux版本封装了sbrk()系统调用,该系统调用负责向操作系统申请内存。malloc函数分配的内存在堆中,全局有效。

  文件:malloc.c

  #include

  #include

  void fenpei1(int **p)

  {

  *p = (int *)malloc(sizeof(int));

  }

  void fenpei2(int *p)

  {

  printf("the heap is %d\n",*p);

  }

  int main(void)

  {

  int *p;

  fenpei1(&p);

  *p=4;

  fenpei2(p);

  free(p);

  fenpei2(p);

  return 0;

  }

  运行:。/malloc

  the heap 4

  the heap 0

  做如下改动:

  void fenpei1(int *p)

  {

  p = (int *)malloc(sizeof(int));

  }

  将fenpei1函数修改为如上形式。嵌入式开发培训传递给fenpei1函数的是int *p的一份拷贝,p在函数返回后就消失了。

  这时,p所指向的还是一块未知区域,再对p进行解引用赋值就出错了。

From  阜和教育

0 0
原创粉丝点击