C语言内存分配

只有一样东西令梦想无法成真,那就是担心失败。

引入

示例

int num[10] = {0};                        //√

int len = 10;

int num[len] = {0};                        //×

因为系统的内存分配原则导致的

概述

在程序运行时,系统为了更好的管理进程中的内存,所以有了将内存进行了分配,其分配机制就称之为内存分配

分配原则

静态分配原则

        特点:

                1.在程序编译或运行过程中,按事先规定大小分配内存空间的分配方式

                 2.必须实现知道所需空间的大小

                3.分配在栈区或全局变量区,一般以数组的形式

                4.按计划分配

动态分配原则

        特点:

                1.在程序运行中,根据需要大小自由分配所需要空间

                2.按需分配

                3.分配在堆区,一般使用特定的函数进行分配

如:

        班级有20个学生,定义数组记录学员的成绩

        double score[20] = {0};

        记录学员成绩

                1.输入学员数量

                2.在堆区申请

                3.扩展

                4.释放

注意

在C语言中提供了一系列动态分配内存的函数,这些函数大部分都在stdlib.h头文件中声明

free                                释放

malloc                            申请空间,默认值随机

calloc                              申请空间,默认值为0

realloc                             扩展空间

string.h中提供的函数

memset        将malloc中的随机数设为0
所以导致申请空间时用那个都一样

动态分配函数

memset函数

作用:重置

语法

#include <string.h>

void *memset(void *s, int c ,size_t n);

参数

        s:开始的位置

        c:重置后的数据

        n:重置的数量

示例

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char strs[10] = {0};
    memset(strs,'a',1*10);
    for (int i = 0; i < 10; i++)
    {
        printf("%c ",strs[i]);
    }
    printf("\n");
    int nums[10] = {1,2,3,4,5,6,7,8,9,0};
    memset(nums,0,4*10);
    for (int i = 0; i < 10; i++)
    {
        printf("%d ",nums[i]);
    }
    printf("\n");
    return 0;
}

free函数

作用:释放空间

语法

#include <stdlib.h>

void free(void *ptr);

参数:

        ptr:指针

malloc函数

作用:在堆内存中开辟空间

语法

void *malloc(size_t   size)

参数:

        size:开辟空间大小,单位为字节,size_t可以理解为无符号int

返回值:

        开辟空间的地址

        开辟失败返回NULL

注意:

        1.在使用malloc需要判断是否开辟成功

        2.如果多次使用malloc申请内存,在第一次和第二次申请的内存不一定是连续的

        3.malloc的返回值在使用时需要进行强制类型转换

        4.malloc从堆区申请空间后,空间内容中的值是随机的(与局部变量相同,大概率值为0),可以使用memset函数对空间中的值进行重置

示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    //1.申请内存空间
    //申请一个可以存储10个int数据空间
    int *p = (int *)malloc(sizeof(int) * 10);
    //2.判断是否开辟失败
    if (p == NULL)
    {
        printf("开辟失败\n");
        return 0;
    }
    //重置为0
    memset(p,0,4* 10);
    //3.使用空间
    for (int i = 0; i < 10; i++)
    {
        printf("%d ",p[i]);
    }
    printf("\n");
    //4.释放空间
    free(p);
    return 0;
}

calloc函数

作用:在堆内存在开辟空间

语法

void *calloc(size_t  nmemb, size_t  size) ;

参数:

        nmemb:申请的块数

        size:每块的大小

返回值:

        开辟空间的地址

        开辟失败时返回NULL

int *p = malloc(sizeof(int) * 10);

int *p = calloc(sizeof(int) * 10);

示例

include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    //1,申请空间
    //申请一个可以存储10个int数据的空间
    // int *p = (int *)malloc(10 * sizeof(int));
    int *p = (int *) calloc(10,sizeof(int));
    //2,判断是否开辟失败
    if (p == NULL)
    {
        printf("开辟失败\n");
        return 0;
    }
    //置0
    //memset(p,0,10 *sizeof(int));
    //3,使用空间
    for (int i = 0; i < 10; i++)
    {
        scanf("%d",&p[i]);
    }
    for (int i = 0; i < 10; i++)
    {
        printf("%d ",p[i]);
    }
    printf("\n");
    //4,释放空间
    free(p);
    return 0;
}
realloc函数

作用:扩展空间

语法

void *realloc(void * ptr,size_t  size);

参数:

        ptr:原指针

        size:从新开辟大小的大小,原大小 + 新开辟的大小

返回值:

        开辟成功返回新地址

        开辟失败返回NULL

注意:

        新地址不一定等于原地址,但是大概率相同

内存泄漏

概念

类似于申请的内存首地址丢了,找不到了,没法使用了,没法释放了,这些情况称之为内存泄漏

情况1:记录申请内存的指针变量指向了别的地方

int *p = (int *) malloc(40);

int nums[10] = {};

p = nums;

情况2:在函数中申请空间,但使用完毕没有释放

void test()

{

        int *p  = (int *)malloc(40);

}

test();

防止多次释放

示例

int *p = (int *)malloc(40);

free(p);

free(p);

//多次释放时会报错

要点:释放前判断,释放后置NULL

int *p = (int *)malloc(40);

if (p != NULL)

{

        free(p);

        p = NULL;

}

if (p != NULL)

{

        free(p);

        p = NULL;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值