解密动态内存管理的奥秘(含内存4个函数)

这篇具有很好参考价值的文章主要介绍了解密动态内存管理的奥秘(含内存4个函数)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

解密动态内存管理的奥秘(含内存4个函数),C语言,数据结构,c语言,c++


目录

一.为什么存在动态内存管理

二.动态内存函数的介绍

1. malloc函数(memory  alloc  内存开辟)

函数介绍:

malloc函数使用举例代码:

2.free(释放) 

函数介绍:

代码的示例:

3.calloc

函数介绍:

代码示例:

运行结果:

4.realloc

函数介绍:

使用示例代码:

常见的动态内存管理的错误

1.对NULL指针进行解引用操作

2.对动态开辟的空间越界访问

3.对非动态开辟的空间使用free

4.使用free释放一块动态开辟的内存中的一部分

5.对同一块内存多次释放

6.动态内存开辟忘记释放,造成内存泄漏


一.为什么存在动态内存管理

我们常见的内存开辟方式:

int  a =  20;               //在栈空间上开辟四个字节

int  arr[10] = { 0 };     //在栈空间上开辟40个字节

但是上的开辟空间方式有两个特点:

1.开辟的空间的大小是固定的;

2.数组在申明的时候,必须指定固定的长度,它所需的内存在编译时分配,有可能用不完造成浪费,也有可能后期不够用;

但是下在我们实际所需求中,不仅仅是上面的两种情况,有时候我们需要的空间大小在程序运行时才知道,那么上述方式开辟空间就不能够满足,所以有了动态内存开辟。

二.动态内存函数的介绍

必备知识:

内存大概的划分:

栈区: 主要存放局部变量,形式参数等等

堆区: 动态内存的开辟,malloc,free,calloc,realloc等等

静态区: 全局变量,静态变量等等

解密动态内存管理的奥秘(含内存4个函数),C语言,数据结构,c语言,c++

1. malloc函数(memory  alloc  内存开辟)

函数介绍:

void*   malloc(size_t    size)

malloc函数可以向内存申请一块连续的空间,并返回指向这块空间的指针;

值得注意的是:

1. 如果开辟成功,将返回一个指向开辟好了的空间的指针;

如果开辟失败,将返回空指针NULL;

所以在开辟后需要判断是否开辟成功,检查返回值;

2. 函数返回的是空指针,malloc函数并不知道开辟空间的类型,所以在使用的时候需要自己决定(使用强制类型转换);

3.如果size为0时,malloc函数的行为是未定义的,取决于编译器;

4.malloc函数开辟的空间里面存放的是随机值(下面代码可验证);

5.malloc函数申请的空间,当程序退出时,还给操作系统,当程序不退出时,动态开辟的空间不会主动还给操作系统,需要用free函数来释放;

malloc函数使用举例代码:

int main()
{
	int* p = (int *)malloc(40);   //这里需要的是int*类型的指针,所以用()强制类型转换为int*
	if (p == NULL)
	{
		perror(malloc);           //判断是否开辟成功
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d\n",*(p+i));
	}

	free(p);
    p=NULL;         //将p置为空指针,不要让p成为野指针

	return 0;
}

运行结果:

-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451
-842150451

2.free(释放) 

函数介绍:

void*   free (void*  p)

C语言提供的free函数是专门用来做动态内存的释放和回收的

free是用来释放动态开辟的内存

1.如果void* p所指向的内存不是动态开辟的,free函数的行为是未定义的;

2.如果void* p所指向的是NULL(空指针),则free函数什么都不做;

代码的示例:

int main()
{
	int* p = (int *)malloc(40);   //这里需要的是int*类型的指针,所以用()强制类型转换为int*
	if (p == NULL)
	{
		perror(malloc);           //判断是否开辟成功
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d\n",*(p+i));
	}

	free(p);       //使用完该空间后释放
    p=NULL;         //将p置为空指针,不要让p成为野指针

	return 0;
}

3.calloc

函数介绍:

void*   calloc (size_t  num , size_t   size)

功能:是为num个大小为size的元素开辟一块空间,并吃初始化为0;

与malloc函数类似,只是会将开辟的空间内容初始化为0;

代码示例:

int main()
{
    int* p = (int* )calloc(40,sizeof(int));
	if (p == NULL)
	{
		perror(calloc);
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ",*(p+i));
	}
	free(p);
	p = NULL;

	return 0;
}

运行结果:

0   0   0   0   0   0   0   0   0   0

4.realloc

realloc函数可以让内存管理更加灵活;

函数介绍:

viod*   realloc    (void*   ptr,size_t   size)

realloc函数可以调整我们申请的空间的大小;

其中ptr是要调整的内存地址;

size是调整之后的大小;

返回值是为调整之后的内存起始位置;

当void*  ptr  为一个空指针时,功能和malloc一样;

值得注意的是:这个函数调整之后,可能将原来内存中的数据移动到新的空间;

分为两种情况;

1.原有空间的后面有足够大的空间时(即原有空间后面的剩余空间有所需增加空间那么大),就直接在原有空间后面开辟,并且返回指向原来空间的指针;

2.当原有的空间后面没有足够大的空间来增加空间,则需要重新找一个空间开辟,并且将原有空间的内容复制过去,然后释放旧的空间的内存,返回新的地址;

使用示例代码:

int main()
{
	int* p =(int* )malloc(40);
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		p[i] = i+1;
	}
	int* ret = realloc(p,80);
	{
		if (ret == NULL)
		{
			perror("realloc");
			return 1;
		}
		else
		{
			p = ret;
		}
	}

	for (i = 0; i < 20; i++)
	{
		printf("%d ",*(p+i));
	}

	free(p);
	p = NULL;


	return 0;
}

运行结果:

1  2  3  4  5  6  7  8  9  10  -842150451  -842150451  -842150451  -842150451  -842150451  -842150451  -842150451  -842150451 -842150451 -842150451

常见的动态内存管理的错误

1.对NULL指针进行解引用操作

      void   test

     {   

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

              *p = 20;    //如果p是空指针就有问题;

               free(p);

     }

当用内存函数开辟好空间后,不检查是否开辟成功就直接使用;

2.对动态开辟的空间越界访问

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

int i = 0;

for(i=0;i<12;i++)                  //  i=10,11,就越界访问了

{

     printf("%d ",*(p+i));

}

3.对非动态开辟的空间使用free

int a = 10;

int* p = &a;

free(p);            //  错误的

4.使用free释放一块动态开辟的内存中的一部分

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

p++;

free(p);           //p++后,已经不是指向的原开辟的内存,而是指向的一部分;

5.对同一块内存多次释放

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

free(p);

free(p);

6.动态内存开辟忘记释放,造成内存泄漏

void   test()

{

         int * p =(int*)mmalloc(40)

          if(NULL!=p)

          {

                 *p=20;

          }

                                                     //使用完后忘记释放,出函数p销毁,但是40个字节的空间还在

int  main()

{

         test();

          while(1);                               //死循环,程序不结束,40个字节永远用不到

}

                                                             作者:GOXXT

                                                             专注分享在学习道路上的知识笔记文章来源地址https://www.toymoban.com/news/detail-601853.html



到了这里,关于解密动态内存管理的奥秘(含内存4个函数)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构之动态内存管理机制

      目录 数据结构之动态内存管理机制 占用块和空闲块 系统的内存管理 可利用空间表 分配存储空间的方式 空间分配与回收过程产生的问题 边界标识法管理动态内存 分配算法 回收算法 伙伴系统管理动态内存 可利用空间表中结点构成 分配算法 回收算法 总结 无用单元收集(

    2024年02月12日
    浏览(42)
  • 【C语言】动态内存函数介绍

    目录 1.malloc和free 2.calloc 3.realloc   C语言提供了一个动态内存开辟的函数malloc: 这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。 ✔如果开辟成功,则返回一个指向开辟好空间的指针。 ✔如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做

    2024年01月22日
    浏览(34)
  • 【C语言】free()函数详解(动态内存释放函数)

    🦄 个人主页 :修修修也 🎏 所属专栏 :C语言 ⚙️ 操作环境 : Visual Studio 2022 目录  一.free()函数简介 1.函数功能 2.函数参数 void * ptr 3.函数返回值 4.函数头文件 二.free()函数的具体使用 1.使用free()函数完成malloc()开辟空间的释放 2.使用free()函数完成calloc()开辟空间的释放 3.使用

    2024年02月08日
    浏览(39)
  • 「探索C语言内存:动态内存管理解析」

    🌠先赞后看,不足指正!🌠 🎈这将对我有很大的帮助!🎈 📝所属专栏:C语言知识 📝阿哇旭的主页:Awas-Home page 目录   引言 1. 静态内存 2. 动态内存 2.1 动态内存开辟函数 2.1.1 malloc函数 2.1.2 calloc函数 2.1.3 realloc函数 2.2 动态内存释放函数 2.2.1 free函数 3. 动态内存的常见

    2024年04月28日
    浏览(41)
  • C语言 malloc动态内存分配函数

    malloc函数:malloc时动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,就是当数组创建长度不一定 害怕数据存储不够或者不能浪费时间 在使用malloc开辟空间时,使用完成一定要释放空间,如果不释放会造内存泄漏。n在使用ma

    2024年02月07日
    浏览(46)
  • [C语言][数据结构][动态内存空间的开辟]顺序表的实现!

    目录 零.必备知识 a.顺序表的底层是数组. b.数组在内存中是连续存放的. c.动态内存空间的开辟(malloc,calloc,realloc). 一.顺序表的定义与实现          1.1 顺序表的定义          1.2 顺序表的初始化          1.3 顺序表的销毁          1.4 顺序表容量的检查与调整

    2024年04月09日
    浏览(88)
  • 动态内存管理-c语言

    目录 1.为什么要有动态内存分配 2.malloc函数和free函数 malloc 函数原型 栗子 free 函数原型 栗子 3.calloc和***realloc*** 3.1calloc函数 原型如下: 栗子 3.2***recalloc*** 第一种情况 第二种情况 第三种情况 recalloc模拟实现calloc函数 4.六大常⻅的动态内存的错误 4.1对NULL指针的解引⽤操作

    2024年03月22日
    浏览(38)
  • c语言-动态内存管理

    1.我们一般的开辟空间方式: 2.这样开辟空间的特点 (1)申请的空间大小是固定的 (2)像数组那样一开始就要确定大小,一旦确定大小就不能改变了 3.动态内存 对于程序来说上述的内存申请是不能满足 因此为了能够对内存进行调整,C语言引入了动态内存开辟,让程序员自

    2024年02月04日
    浏览(36)
  • C语言->动态内存管理

    文章目录  ✅作者简介:大家好,我是橘橙黄又青,一个想要与大家共同进步的男人😉😉 🍎个人主页:橘橙黄又青_C语言,函数,指针-CSDN博客 目的:学习malloc,free,calloc,realloc函数的使用。 内存函数在#includestdio.h头文件里面。 我们已经掌握的内存开辟⽅式有: 但是上述的

    2024年02月04日
    浏览(50)
  • C语言:动态内存管理

    先点赞再观看哦! 学习数据结构之前,一定要对指针、结构体、动态内存管理进行深入学习! 小伙伴们可以看看博主之前的文章! 今天重点介绍动态内存开辟!十分重要哈! 我们已知的内存开辟方式有什么呢?? 但是上述开辟的空间有三个特点: 1、空间开辟的大小是固定

    2024年01月22日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包