动态内存管理

在空间使用未知的情况下,如果使用数组,就必须事先指定申请的空间大小,当数据太大数组空间不足以存储,当数据太小又会造成空间的浪费。所以,我们要学会动态内存开辟。


动态内存函数

malloc

void* malloc(size_t size);
//size表示要申请的空间的大小,单位字节

函数向内存申请一块连续的内存空间:

  • 如果申请成功,返回指向该空间的指针

  • 如果申请失败,返回NULL指针

  • 函数返回类型是void*,所以使用时要进行类型转换


calloc

void* calloc(size_t num, size_t size);
//num表示要申请的元素的个数
//size表示每个元素的大小,单位字节

函数向内存申请能够存储num个大小为size的元素的连续空间,并把空间的每个字节都初始化为0。与malloc功能的唯一区别就是初始化空间。

  • 如果申请成功,返回指向该空间的指针

  • 如果申请失败,返回NULL指针

  • 函数返回类型是void*,所以使用时要进行类型转换


realloc

void* realloc(void* ptr, size_t size);
//ptr表示一个曾用malloc,calloc,realloc申请过的内存的指针,如果是NULL,则新开辟一块空间
//size表示size表示调整后的空间的总大小,单位字节

函数可以通过空间指针对已经申请过的空间进行调整

  • 如果申请失败,返回NULL空指针

  • 如果申请成功,返回的指针分为两种情况:

  1. 原有空间之后的空间大于调整后空间的大小,那么返回的指针就是调整之前的空间的指针

  1. 原有空间之后的空间不够大,小于调整后空间的大小,函数会在向内存再申请一块空间,将之前空间的数据拷贝,并释放之前申请的空间,返回新申请的内存空间地址。

  • 如果传入的指针是NULL,则会开辟一块新空间,作用与malloc无异


free

void free(void*ptr);
//ptr表示要释放的空间地址

函数对通过动态开辟的内存进行释放

  • free不可对不是动态开辟的内存进行释放

  • 如果传入的指针是NULL,则函数不进行任何操作

  • free不可对动态开辟的内存而此释放

  • free后的空间指针不会置NULL


常见的动态内存错误

对NULL指针的解引用操作

int main()
{
    int* p = (int*)malloc(INT_MAX/4);
    *p = 20;
    free(p);
    p = NULL;
    return 0;
}

INT_MAX是一个非常大的数,动态开辟时可能不成功,p就是空指针,对它解引用会出错。

所以动态开辟后要对指针进行检查


对动态开辟空间的越界访问

void test()
{
    int i = 0;
    int *p = (int *)malloc(10*sizeof(int));
    if(NULL == p)
    {
        exit(EXIT_FAILURE);
    }
    for(i=0; i<=10; i++)
    {
        *(p+i) = i;//当i是10的时候越界访问
    }
    free(p);
}

对非动态开辟内存使用free释放

void test()
{
    int a = 10;
    int *p = &a;
    free(p);//ok?
}

使用free释放一块动态开辟内存的一部分

void test()
{
    int *p = (int *)malloc(100);
    p++;
    free(p);//p不再指向动态内存的起始位置
}

对同一块动态内存多次释放

void test()
{
    int *p = (int *)malloc(100);
    free(p);
    free(p);//重复释放
}

动态开辟内存忘记释放(内存泄漏)

void GetMemory(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");
    printf(str);
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值