现在的位置: 首页 > 综合 > 正文

Linux的内存结构以及动态申请的几个函数

2017年11月17日 ⁄ 综合 ⁄ 共 1324字 ⁄ 字号 评论关闭

在Linux系统中,一个进程的内存分为以下几个部分;

文本段:包含着进程的代码、程序中的常量和只读数据

堆栈段:又叫做栈,保存程序的局部变量和函数返回值。

堆段:又叫做堆,是进程的动态存储空间。

BSS段:包含了未初始化的全部变量。全局变量常常初始化为0,但是在程序中并没有保存全局变量的值。一方面这可以减小二进制可执行文件的大小;另一方面,内核在装载BSS段时,只需将它映射到一个全是0的页上,这样就可以完成了初始化。


在程序的执行过程中,常常需要动态内存的分配。动态内存分配有以下几个函数

1、malloc

原型:

#include<stdlib.h>

void *malloc(size_t size);

成功调用会得到size大小的内存区域,返回指向这个内存的首地址指针。但是要注意,这个内存的内容是未知的。

失败是返回NULL,设置erron为ENOMEM。

2、calloc

函数原型:

#include<stdlib.h>

void *calloc(size_t nr, size_t size)

这个函数为数组开辟内存比较方便,成功调用后返回一个数组内存的首地址(nr个数组元素,每个元素占size个字节)。并且会把开辟的内存用0初始化。

失败返回NULL,设置errno为ENOMEM。

3、realloc

函数原型

#include<stdlib.h>

void *realloc(void *ptr, size_t size)

这个函数可以改变已经申请的动态内存的大小(变大或变小)。调用成功后,将prt指向的内存区域变为size字节,返回新的空间指针。

如果扩大内存时,返回的指针可能不再是ptr。当realloc不能在已有的空间上增加到size大小事,就会在其他地方申请一块大小为size的内存 空间,将原有的数据拷贝到新空间,之后释放就空间。如果有数据的拷贝,调用会比较耗时。当size=0时,相当于free;如果ptr=NULL,相当于malloc。

当收缩内存时,返回的指针和ptr指向同一内存,只是内存变小。

调用失败时,返回NULL,并设置errno为ENOMEM。

以上三个函数申请的内存均在堆上,是动态申请的。动态内存将永久占有一个进程的地址空间,直到它被显示释放,所以我们需要手动来释放这些动态申请的内存。

4、free

函数原型

#include<stdlib.h>

void free(void *ptr);

调用free会释放ptr指向的内存。要注意的是,free是释放在堆上动态申请的内存,是释放前面三个函数malloc、calloc、realloc的返回值。当ptr=NULL时,free什么也不做。


动态内存申请一般都是在堆上,在栈上也可以进行动态内存分配的。下面这个函数就是在栈上动态申请内存。

5、alloca

函数原型:

#include<alloca.h>

void *alloca(size_t size);

函数成功调用时,返回一个指向size大小内存的指针,这块内存是在栈上的,当超出作用域范围是将被自动释放。

当函数调用失败时返回NULL,但是一般不会失败,除非栈溢出。

要注意的是分配的内存不能作为调用函数的参数,因为分配的内存会被当做参数保存在函数的栈中,把栈上函数的参数分离开来。

抱歉!评论已关闭.