堆空间的申请和释放

堆空间的特点

heap
对于应用程序而言 栈 bss rodata等等都只是占用整个虚拟地址空间一小部分,更多的空间都可以用分配给堆。

就C语言而言 堆空间中的数据和栈中数据   不一样的地方在于  必须要手动申请和手动释放

堆空间的申请

malloc函数

calloc函数

realloc函数

操作系统的内存分配策略

malloc(31) 和malloc(32)对于操作系统而言是否内存真的少分配一个字节?

堆空间的释放

free()函数

内存泄漏的危害

练习

  1. 给定一段代码分别写出每个变量和函数的作用域、寿命、所处段
#include <stdio.h>

int           a;
int           b  = 10;
static int    c;
static int    d  = 20;
const  double PI = 3.141592657 ;

static void func(void)
{
    printf("fun\n");
}

extern void too(void)
{
    static int j = 60;
    j++;
    printf("%d\n",j);
}

int main()
{
    int e = 30 ;
    int f;
    static int g;
    static int h = 40;
    char *p = "hello";
    func();

    for(f = 0; f < 10;f++)
    {
        int k = 50;
        printf("%d\n",k+1);
        k++;
    }

    too();
    too();
    too();
    return 0;
}
  • 简述内存泄露现象的原因和危害。

  • 库函数calloc有如下声明:

void *calloc(size_t rmemb, size_t Size) ;

根据库文档: “函数calloc为一个数组分配内存,该数组有rmemb个元素,每个元素为size字节。内存设置为00,如果rmemb或size为0,则calloc返回NULL。 编写calloc的实现,通过调用malloc执行分配,调用memset将内存设置为00你的代码应该没有任何由算术溢出引起的漏洞,且无论数据类size_t用多少位表示,代码都应该正常工作。

作为参考,函数malloc和memset声明如下:

  void malloc(size_t Size) ;  
  void memset(void _s, int c, size_t n\);