C语言入门16 动态申请内存和内存泄漏

文章详细介绍了C语言中动态内存分配的概念,包括malloc、free、calloc和realloc函数的使用,以及内存泄漏问题。动态分配允许在程序运行时按需分配内存,malloc分配的内存需要通过free释放,calloc分配的内存会被初始化为0。realloc可以调整已分配内存的大小,但可能导致内存移动。最后,文章通过示例展示了内存泄漏的情况,即分配的内存未被正确释放。
摘要由CSDN通过智能技术生成

一、静态分配和动态分配

  1. 静态分配
    • 在程序编译或运行过程中,按事先规定大小分配内存空间的分配方式,比如int[10];
    • 必须事先知道所需空间的大小。
    • 分配在栈区或者全局变量区,一般以数组的形式。
    • 按计划分配。
  2. 动态分配
    • 在程序运行过程中,根据需要大小自由分配所需空间。
    • 按需分配。
    • 分配在堆区,一般使用特定的函数进行分配。
    • 需要包含头文件include<stdlib.h>

二、动态分配函数

  1. malloc函数:void *malloc(unsigned int size);
    功能说明:在堆区中分配一块长度为size的连续区域,用来存放类型说明符指定的类型。函数原型返回void*指针,使用时必须做相应的强制类型转换,分配的空间内容不确定,一般用memset初始化
    注意:
  • 在调用malloc后,一定要通过返回值判断是否申请内存成功,失败返回NULL
  • 如果多次使用malloc申请内存,第一次和第二次申请的内存不一定是连续的。
int* p = (int*)malloc(n * 4);
  1. free函数:void free(void* ptr);
    释放ptr所指向的内存,ptr指向的内存必须是malloc、calloc、relloc动态申请的内存。
    注意:
  • free某段内存后,原本指向该内存的指针还是没有变,但是内存已经不能够使用了。
  • 一块动态申请的内存只能free一次。
free(p);
  1. calloc函数:void* calloc(size_t nmemb, size_t size);
    size_t,其实就是无符号整型,它是头文件中用typedef定义出来的。
    在内存的堆区中,申请nmumb块,每块的大小为size个字节的连续区域

注意:

  • malloc和calloc都是用来申请内存的。区别在于malloc函数申请的内存内容是随机的,而calloc函数申请的内存内容为0
  • 同样必须判断是否申请成功,如果失败返回NULL
int* p = (int*)calloc(n, 4);
  1. realloc函数:void* realloc(void *s,unsigned int newsize);
    在原先s指向的内存基础上重新申请内存,新的内容大小为newsize个字节,这样一来,就会出现三种情况:
  • (旧的内存大小<newsize)原先内存后面有足够大的空间,那么直接追加
  • (旧的内存大小<newsize)原先内存后面内存不够用,realloc函数回在堆区找一个newsize个字节大小的内存申请,再将原先内存的内容拷贝过来,然后释放原先的内存,最后返回新内存的地址
  • (旧的内存大小>newsize)会释放原先内存后面的存储空间,只保留newsize个字节的空间,返回新申请的首地址。
p = (char*)realloc(p,50);
  1. 内存泄漏(非常严重的问题
    申请的内存,首地址丢了,找不到并且再也没办法使用了,也没法释放,就成为内存泄露。

模拟:

#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[])
{
	char* p;
	p = (char*)malloc(100);//指向新分配的内存
	p = "hello world";//又指向了其他内存
	return 0;
}

最后,一开那100个字节的内存已经无法被找到了,也没有办法进行释放,这就是内存泄漏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值