[学习笔记]c语言中关于内存的详解

什么是内存

内存(Memory)是计算机的重要部件,也称内存储器和主存储器,它用于暂时存放cpu中的运算数据,以及与硬盘等外部存储器交换数据,是外存与cpu沟通的桥梁,计算机中所有的程序运行都在内存中进行。

C语言中内存分区模型

分区名存储内容
代码区存放函数体内的二进制代码 由操作系统管理 代码区的内容是共享的 多次运行同一个程序不会重复占用代码区内存 并且代码区是只读的
全局区/静态区/常量区存放全局变量和静态变量及常量 程序结束后由操作系统释放
栈区由编译器自动分配释放 存放函数的参数值 局部变量等 (高地址向地址 寻址快 地址连续)
堆区由程序员分配和释放 若程序员不释放 程序结束时由操作系统回收(低地址向高地址 寻址慢 地址不连续)

动态分配内存的概述

数组声明时需预先定义数组的长度,且长度固定不变,但是在实际编程中,往往会发生内存空间取决于实际输入数据的情况,无法预先确定,为了解决上述问题,c语言提供了一些内存管理函数,可以按需动态分配内存的空间,也可以把不在使用的内存空间回收。
动态分配内存就是在堆区开辟空间

静态分配内存的概述

在程序编译或运行中,按事先规定好的大小分配内存空间 例如 int a[10]
内存空间分配在栈区或者全局变量区

动态内存函数 malloc

需引入头文件: #include<stdlib.h>
函数原型:void *malloc(unsigned int size)
在堆区中分配一块长度为size字节的连续区域 用来存放类型说明符指定的类型的数据
函数返回值是一个 void*指针 使用时必须做响应的强制类型转换,分配的内存空间内容不确定
一般使用memset 进行初始化
申请成功返回开辟好空间的首地址
若申请失败,返回NULL

调用malloc之后一定要判断一下是否申请成功
多次调用malloc申请内存,地址不一定是连续的

动态内存函数 free

需引入头文件: #include<stdlib.h>
函数原型:void free(void *ptr)
ptr : 开辟的堆区空间的首地址
释放 ptr 指向的内存
前提必须是 malloc,calloc,relloc动态申请的内存

char *p = (char *) malloc(100 * sizeof (char ));
free(p);
由于p被释放后,没有赋值,所以p还是指向原先申请的内存地址,但内存已经不能再用了,p变成野指针了
一块动态申请的内存只能free一次,不能多次free

free函数只能释放堆区空间
free函数释放malloc,calloc,relloc返回值指定的空间,不能只释放一部分
为防止野指针,free之后将p赋值为NULL

动态内存函数 calloc

需引入头文件: #include<stdlib.h>
函数原型:void *calloc(unsigned nmemb,unsigned size);
在内存的堆中,申请nmemb块,每块大小为size个字节的连续区域
函数返回值是一个 void*指针 ,分配的内存空间内容为0
申请成功返回开辟好空间的首地址
若申请失败,返回NULL

malloc分配的内存 内容不确定,calloc默认为0

动态内存函数 relloc

由于连续使用malloc和calloc申请内存时,内存地址不一定是连续的,有时会有需求,在原有内存的基础上挨着申请内存,或者开始使用malloc或者calloc申请一块内存,想释放后面一部分内存。
为满足这个需求,relloc应运而生

需引入头文件: #include<stdlib.h>
函数原型:void *relloc(void *s,unsigned newsize);
在原内存空间s的基础上重新申请内存,新的内存大小为newsize字节,
如果原先内存后面有足够大的连续的空间,即追加,
如果不够,则relloc会在堆区申请一个连续的newsize大小的空间,
把原内容拷过来,再释放原先的内存,最后返回新的内存地址。
如果newsize比原内存小,则会释放原内存多出的空间,只留newsize个字节
申请成功返回新的内存的首地址

内存泄漏

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

内存泄漏的例子1int main() {
    char *p;
    // 使用malloc申请100字节的内存
    p = (char *)malloc(100);
    //紧接着p指向一个字符串
    p = "hello word";
    // 从此之后,你再也找不到此前申请的100个字节了
    // 这块内存就泄漏了
}

内存泄露的例子2void func(){
    char *p;
    // 使用malloc申请100字节的内存
    p = (char *)malloc(100);
}

int main() {
    //每次调用func时 都会申请100个字节的内存
    func();
    func();
    func();
    //没有返回内存的首地址,内存没有被释放,共泄漏300字节的内存
}

申请的内存一定不要把首地址丢了,不用的内存一定要释放,
为防止野指针,free释放内存之后要赋值为NULL

关于内存的知识后续会再补充
今天就这样,出门遛弯了~
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值