动态内存分配

来源:互联网 发布:太平天国失败 知乎 编辑:程序博客网 时间:2024/06/05 15:55

1 动态内存分配的意义

  • C语言中的一切操作都是基于内存的。
  • 变量和数组都是内存的别名:
    • 内存分配由编译器在编译期间决定;
    • 定义数组的时候必须指定数组长度;
    • 数组长度是在编译期就必须确定的。

需求:程序运行的过程中,可能需要使用一些额外的内存空间。

2 malloc和free

  • malloc和free用于执行动态内存分配和释放。

这里写图片描述

  • malloc所分配的是一块连续的内存(不会对内存进行初始化)。
  • malloc以字节为单位,并且不带任何的类型信息
  • free用于将动态内存归还系统。
    • void* mallic(size_t size);
    • void free(void* pointer);

注意:

  • malloc和free是库函数,而不是系统调用。
  • malloc实际分配的内存可能会比请求的多。
  • 不能依赖于不同平台下的malloc行为。
  • 当请求的动态内存无法满足时(可能内存已耗尽或者依次申请的内存字节数太大)malloc返回NULL。
  • 当free的参数为NULL时,函数直接返回。

思考:
malloc(0);将返回什么?

分析:malloc(0)是成功的,理论上来说内存是有起始地址和长度这两种属性的。成功的返回值了起始地址,但是长度为0,因此不能使用。但是实际,可能会返回的比申请的多,所以成功分配并且能够使用。

实例分析:内存泄漏检测模块

main.c

#include <stdio.h>#include "mleak.h"void f(){    MALLOC(100);}int main(){    int* p = (int*)MALLOC(3 * sizeof(int));    f();    p[0] = 1;    p[1] = 2;    p[2] = 3;    FREE(p);    PRINT_LEAK_INFO();    return 0;}

mleak.c

#include "mleak.h"#define SIZE 256/* 动态内存申请参数结构体 */typedef struct{    void* pointer;    int size;    const char* file;    int line;} MItem;static MItem g_record[SIZE]; /* 记录动态内存申请的操作 */void* mallocEx(size_t n, const char* file, const line){    void* ret = malloc(n); /* 动态内存申请 */    if( ret != NULL )    {        int i = 0;        /* 遍历全局数组,记录此次操作 */        for(i=0; i<SIZE; i++)        {            /* 查找位置 */            if( g_record[i].pointer == NULL )            {                g_record[i].pointer = ret;                g_record[i].size = n;                g_record[i].file = file;                g_record[i].line = line;                break;            }        }    }    return ret;}void freeEx(void* p){    if( p != NULL )    {        int i = 0;        /* 遍历全局数组,释放内存空间,并清除操作记录 */        for(i=0; i<SIZE; i++)        {            if( g_record[i].pointer == p )            {                g_record[i].pointer = NULL;                g_record[i].size = 0;                g_record[i].file = NULL;                g_record[i].line = 0;                free(p);                break;            }        }    }}void PRINT_LEAK_INFO(){    int i = 0;    printf("Potential Memory Leak Info:\n");    /* 遍历全局数组,打印未释放的空间记录 */    for(i=0; i<SIZE; i++)    {        if( g_record[i].pointer != NULL )        {            printf("Address: %p, size:%d, Location: %s:%d\n", g_record[i].pointer, g_record[i].size, g_record[i].file, g_record[i].line);        }    }}

mleak.h

#ifndef _MLEAK_H_#define _MLEAK_H_#include <malloc.h>#define MALLOC(n) mallocEx(n, __FILE__, __LINE__)#define FREE(p) freeEx(p)void* mallocEx(size_t n, const char* file, const line);void freeEx(void* p);void PRINT_LEAK_INFO();#endif

3 calloc和realloc

  • malloc的同胞兄弟
    • void* calloc(size_t num, size_t size);
    • void* realloc(void* pointer, size_t new_size);
  • calloc的参数代表所返回内存的内存信息:calloc会将返回的内存初始化为0。
  • realloc用于修改一个原先已经分配的内存块大小(不会对扩大的内存进行初始化):
    • 在使用realloc之后应使用其返回值;
    • 当pointer的第一个参数为NULL,等价于malloc。

实例分析:calloc和realloc的使用

#include <stdio.h>#include <malloc.h>#define SIZE 5int main(){    int i = 0;    int* pI = (int*)malloc(SIZE * sizeof(int));    short* pS = (short*)calloc(SIZE, sizeof(short));    for(i=0; i<SIZE; i++)    {        printf("pI[%d] = %d, pS[%d] = %d\n", i, pI[i], i, pS[i]);    }    printf("Before: pI = %p\n", pI);    pI = (int*)realloc(pI, 2 * SIZE * sizeof(int));    printf("After: pI = %p\n", pI);    for(i=0; i<10; i++)    {        printf("pI[%d] = %d\n", i, pI[i]);    }    free(pI);    free(pS);    return 0;}

小结

  • 动态内存分配是C语言中的强大功能。
  • 程序能够在需要的时候有机会使用更多的内存。
  • malloc单纯的从系统中申请固定字节大小的内存,不会进行初始化。
  • calloc能以类型大小为单位申请内存并初始化为0。
  • realloc用于重置内存大小,扩展出来的部分不会初始化,值是随机的。
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我们约会吧黄丽蓉 我们约会吧 陈文 我们约会吧停播了吗 我们约会吧胖女孩 我们约会吧开场白 我们约会吧 李菲儿 我们约会吧化妆师 我们约会吧 尹浩 我们约会吧开场曲 我们约会吧野新新 我们约会吧王思博 我们约会吧谢小宇 我们约会吧自我介绍 我们约会吧嘉宾资料 我们约会吧余扬 我们约会吧人气女嘉宾 我们约会吧 李帅 我们约会吧王庚 我们约会吧 马施宇 我们约会吧戴锐 我们约会吧 郭佳 我们约会吧韩超 我们约会吧金睿 我们约会吧刘铭 我们约会吧蔡阳史超 我们约会吧天津女嘉宾 我们约会吧开场歌曲 2013我们约会吧 班宁我们约会吧 班宁 我们约会吧 电视节目我们约会吧 谢小宇上我们约会吧 吴丹妮我们约会吧 约人app 约定 约定歌词 死亡约定 约定近义词 幸福约定 你我约定 约定粤语