C语言学习记录——사십유 动态内存管理(1)

C语言学习记录——사십유 动态内存管理(1),第1张

为什么存在动态内存管理

内存有几个区,栈区,堆区,静态区。动态内存分配分配的就是堆区的空间。静态区存放全局和静态变量以及static,栈区存放局部变量,函数的形参。

当前我们有一些声明变量的方式,比如int a = 0这样,也可以声明数组,声明结构体等等,相应的声明的数组是全局的,那就放在静态区。不过现在要想想,当建立数组存储一个班的数据时,我们会面临一个问题,要放多少个学生的数据?

先简单建立一下

#define  _CRT_SECURE_NO_WARNINGS 1
#include

struct S
{
    char name[20];
    int age;
};

int main()
{
    struct S arr[50];//假如只有20个学生,那么就产生空间浪费了
    return 0;
}

最好是想要多大就多大,我们也不能把50换成一个n,然后输入进去的数字放进n的地址,因为数组声明需要用常量表示元素个数

现在来看,这种开辟空间的方式有两个特点:

空间开辟大小固定

数组再申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。

对于开辟空间,有时候事先并不知道,运行后才会知道准确的消息,所以这就需要动态分配

函数

malloc和free

void* malloc(size_t size)size就是开辟的空间字节大小 。

#include

int main()
{
    //向内存申请10个整形的空间
    int* p = (int*)malloc(10 * sizeof(int));
    return 0;
}
不过也有一个问题,malloc开辟空间失败,比如只有1g空间,就无法开辟3g空间。

malloc会返回一个指针,指向那个开辟好的空间。或者返回空指针。

#include
#include
#include
#include

int main()
{
    //向内存申请10个整形的空间
    int* p = (int*)malloc(10 * sizeof(int));
    if (p == NULL)
    {
        //打印错误原因的一个方式
        printf("%s\n", strerror(errno));
    }
    else
    {
        //正常使用空间
        int i = 0;
        for (i = 0; i < 10; i++)
        {
            *(p + i) = i;
        }
        for (i = 0; i < 10; i++)
        {
            printf("%d ", *(p + i));
        }
    }
    return 0;
}
空间使用完还需要返还,需要用到free

void free (void* memblock)

return 0前直接加上free(p)即可。

虽然说不写free,这个程序结束后也会还回去,但是需要整个程序结束才能返还。所以需要free及时清理空间。

#include
#include
#include
#include

int main()
{
    //向内存申请10个整形的空间
    int* p = (int*)malloc(10 * sizeof(int));
    if (p == NULL)
    {
        //打印错误原因的一个方式
        printf("%s\n", strerror(errno));
    }
    else
    {
        //正常使用空间
        int i = 0;
        for (i = 0; i < 10; i++)
        {
            *(p + i) = i;
        }
        for (i = 0; i < 10; i++)
        {
            printf("%d ", *(p + i));
        }
    }
    free(p);
    p = NULL;//空指针是不使用的,这也有效防止p的使用
    return 0;
}

即使free(p)后,p这个指针还是指向那个地址,所以为了防止p继续被使用,地址安全,所以需要赋值为空。

如果size为0,那么malloc的这种行为是标准未定义的,c语言没有专门的说明,这样就会编译器不同,malloc就不同

free要释放的空间必须是动态开辟的,否则也是标准未定义的

如果是空指针,那么free什么也不做

结束。
 

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/872753.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存