0
点赞
收藏
分享

微信扫一扫

C语言 DAY10 内存分配

书坊尚 2023-11-03 阅读 20

1.引入

        int nums[10] = {0}; //对

        int len = 10;

        int nums[len] = {0}; //错

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

2.概述

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

1.静态分配原则

        1.特点

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

                2、必须事先知道所需空间的大小。

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

                

                4、按计划分配

  2.动态分配原则

        1.特点

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

                2、按需分配。

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

        案例

                班级有15个学员,定义数组记录学员成绩

        double score[15] = {0};

        记录学员成绩

        1,输入学员数量

        2,在堆区申请

        3,扩展

        4,释放

注意

                

c 语言中提供了一系列动态分配内存的函数

这些函数大部分都在 stdlib.h 头文件中声明

free 释放

malloc 申请空间 , 默认值随机

calloc 申请空间 , 默认值为 0

realloc 扩展空间

string.h 中提供的函数

memset malloc 中的随机数设为 0

3.动态内存分配    

memset函数

作用:重置

语法:

#include <string.h>

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

s:原指针

c:重置后的数据

n:重置的数量

s开始,n个字节的数据,设置为c

示例:     

#include<stdio.h>

#include<string.h>

int main(int argc, char const *argv[])

{

        char strs[10] = {0};

        memset(strs,'a',10*1);

        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,10};

        memset(nums,0,10 * 4);

        for (int i = 0; i < 10; i++)

        {

        printf("%d ",nums[i]);

        }

        printf("\n");

        return 0;

}

free函数

作用:释放空间

语法:

        #include<stdlib.h>

        void free(指针变量名);

malloc函数

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

语法:

        #include<stdlib.h>

        void *malloc (size_t size);

参数:

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

返回值:

        开辟的空间的地址

        开辟失败返回NULL

注意:

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

        2,如果多次 malloc 申请的内存,第 1 次和第 2 次申请的内存不一定是连续的

        3,malloc的返回值在使用中记得强制类型转换

        4,malloc从堆区申请空间后 空间的内容中的值是随机的(与局部变量一样大概率为0),可以使用

memset函数对空间中的数据进行置

示例:

       

#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));

//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;

}

calloc函数

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

语法:

#include <stdlib.h>

void *calloc(size_t nmemb, size_t size);

参数:

        nmemb:申请的块数

        size:每块的大小

返回值:

        开辟的空间的地址

        开辟失败返回NULL

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

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

示例:   

#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

注意 :

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

示例:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    int *p = (int *)calloc(3,sizeof(int));
    int *p2 = (int *)calloc(3,sizeof(int));
    //...
    p = realloc(p,20);
    for(int i = 0; i < 5; i++)
    {
        scanf("%d",&p[i]);
    }
    for(int i = 0; i < 5; i++)
    {
        printf("%d,",p[i]);
    }
    printf("\n");
    free(p);
    return 0;
}

 

4.内存泄露

概念:      

        申请的内存,首地址丢了,找不了,再也没法使用了,也没法释放了,这块内存就被泄

露了。

情况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;

}

举报

相关推荐

c语言学习日记—day10

Day10

day10

C语言内存分配

(Day10)String方法

Java Web day10

day10 - 函数基础

C语言的内存分配

0 条评论