10.1 动态内存分配与释放

C语言第四种分配内存的方法

        1.变量做不到一次性大量分配

        2.数组可以大量分配,数据类型一致

        3.结构体虽然可以数据类型不一样但是难以大量分配内存,若要大量分配内存要借助数组,数组分配内存类型又一致

前三种分配内存涉及到使用的范围和内存生命周期问题

        4.动态内存分配,一次性大量分配内存,可以数据类型不一致,可以不用关心内存生命周期,只要程序不退出且不调free函数,则malloc分配的内存将一直存在,只有退出和free才会释放。没有局部,全局,静态等内存关系

        缺陷:从堆区分配,不够无法扩大,分配的效率比较低

分配内存:

        #include

        void* malloc (size_t size);

                从堆中分配size字节内存

                成功返回该内存块的起始地址,失败返回NULL。

                对所分配的内存不做初始化

                若size取0,则返回NULL或者一个唯一的地址,保证后续对free函数的调用能够成功

代码如下:

//变量分配内存:少量分配,做不到大量分配
//数组分配内存:可以大量分配,数据类型一致
//结构体分配内存:数据类型不一致,如果要大量分配内存,还得借助数组,数组分配内存类型又一致
//前三种分配内存涉及到使用的范围和内存生命周期问题
//动态内存分配:可以大量分配,可以数据类型不一致,可以不用关心内存生命周期
//动态分配的内存只要不调用free或者程序不退出,内存一直在,只能从堆区分配内存,分配内存效率低
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int *p = NULL;
    //调用动态内存分配函数malloc分配内存
    p = (int *)malloc(8); //连续分配8字节内存,返回分配的内存首地址给p,若不强转则是无类型
    if(p == NULL) {
        printf("分配失败.\n");
        return -1;
    }
    //一旦分配成功,后面如何访问不就是之前讲过的利用指针的三大方法任意访问分配的内存玩法
    printf("分配成功,分配的内存首地址:%p\n", p);
    *(p + 0) = 520; //向前4字节内存写入520
    *(p + 1) = 521; //向后4字节内存写入521
    printf("%d, %d\n", p[0], p[1]);
    //调用free函数主动释放分配的内存,防止内存泄露
    free(p);
    //*p = 520; //还真可以
    p = NULL; //好习惯,否则p就是一个野指针,p指向的内存已经被释放了,不再合法有效
    return 0;
}

calloc:

        (1) #include

                void* calloc(size_t nmemb, size_t size); //nmemb是这块内存要分配的元素个数,size是每个元素的内存大小

        (2) 从堆中分配包含nmember个元素的数组,其中每个元素占size字节

        (3) 分配成功返回该数组的起始地址,失败返回NULL

        (4) 对所分配数组的每个元素,用相应类型的0初始化

示例:

//动态内存分配库函数:calloc
#include <stdio.h>
#include <stdlib.h>
#define NUMB    (4) //利用宏初始化数据个数
int main(void) {
    int *p = NULL;
    //调用动态内存分配函数calloc分配内存
    p = (int *)calloc(NUMB, sizeof(int)); //连续分配16字节内存,返回分配的内存首地址给p
    if(!p) {
        printf("分配失败.\n");
        return -1;
    }
    //一旦分配成功,后面如何访问不就是之前讲过的利用指针的三大方法任意访问分配的内存玩法
    printf("分配成功,分配的内存首地址:%p\n", p);
    //初始化分配的16字节内存
    for(int i = 0; i < NUMB; i++) 
        p[i] = i + 1;
    //打印
    for(int i = 0; i < NUMB; i++)
        printf("%d ", *(p + i));
    printf("\n");
    //调用free函数主动释放分配的内存,防止内存泄露
    free(p);
    //*p = 520; //还真可以
    p = NULL; //好习惯,否则p就是一个野指针,p指向的内存已经被释放了,不再合法有效
    return 0;
}

realloc:

        调整,给malloc分配后的内存进行调整,但是很少使用

        因为垃圾回收不太好的话就会有碎片化内存,会产生malloc后的内存的后续内存不够,此时计算机会找一块大内存,把原来的数据再拷贝过去,而程序运行慢就慢在这里,拷贝越多越慢,且不一定可以找到这么大的内存,会失败。

示例:

//动态内存分配库函数:realloc
#include <stdio.h>
#include <stdlib.h>
int main(void) {
    int *p = NULL;
    //调用动态内存分配函数malloc分配内存
    p = (int *)malloc(8); //连续分配8字节内存,返回分配的内存首地址给p
    if(p == NULL) {
        printf("分配失败.\n");
        return -1;
    }
    //一旦分配成功,后面如何访问不就是之前讲过的利用指针的三大方法任意访问分配的内存玩法
    printf("分配成功,分配的内存首地址:%p\n", p);
    *(p + 0) = 520; //向前4字节内存写入520
    *(p + 1) = 521; //向后4字节内存写入521
    printf("%d, %d\n", p[0], p[1]);
    //调用realloc调整内存大小
    p = realloc(p, 16); //在原先malloc分配的8字节内存后面继续额外多分配8字节内存
    //初始化分配的16字节内存
    for(int i = 0; i < 4; i++) 
        p[i] = i + 1;
    //打印
    for(int i = 0; i < 4; i++)
        printf("%d ", *(p + i));
    printf("\n");
                        //并且返回整个内存的首地址给p
    //调用free函数主动释放分配的内存,防止内存泄露
    free(p);
    //*p = 520; //还真可以
    p = NULL; //好习惯,否则p就是一个野指针,p指向的内存已经被释放了,不再合法有效
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值