我的创作纪念日———C/C++之动态内存管理

这篇具有很好参考价值的文章主要介绍了我的创作纪念日———C/C++之动态内存管理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:点我进入主页

专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

C语言刷题

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂。

目录

 1.前言  

2.为什么要有动态内存分配

3.malloc函数和free函数

4.calloc函数

5.realloc函数

6.小总结 

7.常见的错误(练习)

7.1

7.2 

7.3

8.柔性数组


 1.前言  

      在上一次的内容中我们写了一个通讯录的小程序,可以点击静态通讯录,在这个程序中存在一些局限性,首先是这个程序只能存固定的个数,一旦超过了这个最大的储存个数就不能存储了,第二个就是当我们退出程序后写的数据就会销毁,不能保存。今天我们就学习如何解决储存上限的问题,想要解决这个问题就需要我们的动态内存规划来解决,这里面包括malloc函数,free函数, calloc函数,realloc函数,接下来就让我们看看其中的乐趣吧。

2.为什么要有动态内存分配

        对于一个数组空间开辟大小是固定的。数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。这时候就只能试试动态存开辟了。简单来说我们开辟的内存是固定的,当不够用或者开辟的空间过多时会造成空间的浪费。

3.malloc函数和free函数

        我们进入cplusplus网站malloc查看malloc函数的参数和返回值我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

        参数为size_t size这个参数的内容是开辟多少多少字节,返回值为void*由于我们开辟的空间可以是任意类型的,所以为void*类型。

我们同样搜索free函数的参数和返回值,

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

 free函数是专门释放动态开辟的内存,如果参数ptr指向的不是动态开辟的则什么也不做,如果参数ptr指向NULL,什么也不做。我们写一个代码来展示一下malloc函数和free函数的使用,详细代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* p = (int*)malloc(sizeof(int) * 3);
	int i = 0, * ptr = p;
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	for (i = 0; i < 3; i++)
	{
		*ptr = i;
   		ptr++;
	}
	ptr = p;
	for (i = 0; i < 3; i++)
	{
        printf("%d ", *ptr);
		ptr++;
	}
	free(p);
	p = NULL;
	return 0;
}

运行结果如下:

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

4.calloc函数

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

        我们看到它的第二个参数是size_t size,它是指想要开辟的数据一个元素所占用的空间,第一个参数size_t num是指想要开辟几个大小为size的空间,calloc函数和malloc函数类似,返回值也是void*,我们写一个代码来展示一下calloc函数开辟的空间

#include <stdio.h>
#include <stdlib.h>
int main()
 {
	int* p = (int*)calloc(10, sizeof(int));
	if (p == NULL)
	{
		perror("calloc");
		return 1;
	}
	free(p);
	p = NULL;
	return 0;
}

但是calloc函数和malloc函数有一些不同,calloc函数会讲内存中的值全部初始化为0;

5.realloc函数

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

        它的第一个参数是想要操作的指针,第二个参数是想要扩容到多少所占的空间,realloc函数的出现让动态内存管理更加灵活。有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小的调整。(这里也就是我们通讯录需要扩容操作需要用到的函数)在这里我们通过对通讯录进行扩容来展示一下realloc函数的用法。在这里我们需要增加一个扩容函数详细代码如下:

void addnum(Struct* pc)
{
	if (pc->i == pc->num)
	{
		struct xinxi*ptr = (struct xinxi*)realloc(pc->arr , (pc->num +2)*sizeof(struct xinxi));
		if (ptr != NULL)
		{
			pc->arr = ptr;
			pc->num = pc->num + 2;
		}
		else
		{
			perror("addnum->realloc");
			return;
		}
	}
}

对于realloc函数它有两种开辟空间的方式第一种

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

如果ptr后面的空间足够扩容的空间,那么会直接在这块空间进行扩容;

第二种我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言         ptr后面的空间不足以进行扩容操作,会重新开辟一个空间,将原来的数据拷贝过来,释放原来的空间,并且重新指向新开辟的空间。

6.小总结 

        对于maloc函数和calloc函数和realloc函数,他们都可以被free函数进行释放,他们开辟的空间在堆区,calloc函数开辟后数据全部初始化为0,realloc是专门进行内存扩容。

7.常见的错误(练习)

7.1

void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}

        我们看传的是指针我们直到在创建函数的时候参数是再次创建的,让他进行malloc开辟空间不是让str开辟我们大概可以画为

我的创作纪念日———C/C++之动态内存管理,C语言进阶,c语言

7.2 

char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

        这里会对野指针的错误引用,在函数中char p[] = "hello world"是在栈区开辟的由于函数结束,内存会销毁,让p成为野指针,从而造成str指向野指针,使程序错误。

7.3

void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}

        在这里由于free()造成str成为野指针,strcpy()对野指针访问,造成错误。

8.柔性数组

        也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。
C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
例如我们创建一个柔性数组:

#include <stdio.h>
#include <stdlib.h>
struct num {
	int i;
	int arr[];
}s;
int main()
{
	size_t sz = sizeof(s);
	printf("%d\n", sz);
}

        其中arr就是柔性数组,柔性数组有哪些特点呢?结构中的柔性数组成员前面必须至少一个其他成员。sizeof 返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。(简单来说定义柔性数组必须在它的前面有至少一个结构体的成员,柔性数组不占用内存,柔性数组可以通过动态内存进行开辟空间)

#include <stdio.h>
#include <stdlib.h>
struct num {
	int i;
	int arr[];
}s;
int main()
{
	struct num* p = (struct num*)malloc(sizeof(struct num)+100*sizeof(int));
	int i;
	for (i = 0; i < 100; i++)
	{
		p->arr[i] = i;
	}
	free(p);
	p = NULL;

}

         柔性数组和动态规划类似,我们可以把他们看成一个东西,这样会更好的去理解,今天的内容就结束了,欢迎大家来三连。文章来源地址https://www.toymoban.com/news/detail-738711.html

到了这里,关于我的创作纪念日———C/C++之动态内存管理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 我的1827创作纪念日

    习惯性早上打开电脑,看看CSDN上的资讯,了解行业动态、当前新的技术和大佬的分享。自己动手写应该是2019 年 01 月 08 日,当时应该是在用安装和使用Oracle,遇到一些问题,写下第一篇博客 Oracle存储过程常见问题及解决方法,转眼已过去五年,同时也是参加工作的第五年,

    2024年01月16日
    浏览(44)
  • 我的创作纪念日——512

    没想到不知不觉在CSDN创作就 512 天了,想到一开始就仅仅想在CSDN记笔记,到现在成为一个小博主,认识到了很多志同道合的伙伴,中间创作我也曾经懒惰过,放弃过,但我一次又一次重新进行创作,虽然我是上了大学才开始了解程序员,成为程序员(可能现在还不合格),但

    2024年02月11日
    浏览(51)
  • 我的创作纪念日(划水...)

    提示:可以和大家分享最初成为创作者的初心 例如: 实战项目中的经验分享 日常学习过程中的记录 通过文章进行技术交流 … 提示:在创作的过程中都有哪些收获 例如: 获得了多少粉丝的关注 获得了多少正向的反馈,如赞、评论、阅读量等 认识和哪些志同道合的领域同行

    2023年04月25日
    浏览(52)
  • 我的创作纪念日-哈市雪花

    2018年4月13写了第一篇博客,在此之前也在用CSDN,但更多的是查阅资料,学习技术。在这之前也写过技术文章,记得最开始是在知乎上发表的,终于那一天在微博上看到大佬转换笑脸动画表情的实现思路,一时兴起用WPF实现了下,然后把文章发表在了CSDN上。 文章总是有意义的

    2023年04月16日
    浏览(43)
  • 我的创作纪念日(256天)

    我与csdn的结缘,之前在创作纪念日(128天)便已提到,今在此便不再多言 很惭愧,自六月底至八月中旬,因为忙于找工作,奔赴面试求职之际,写博客没有像之前那么勤, 但也创作了12篇博客,有幸获得1500位粉丝的关注 。其中仅有两篇博客进入热榜,最近一篇文章《Git:在

    2024年02月12日
    浏览(51)
  • 创作纪念日-我的第1024天

    不知不觉已经成为创作者的第1024天啦… … 刚开始接触博客的初衷就是为了记笔记📒、记总结📝,或许对于当时就等同于是为了找工作。 坚持学习并持续输出博客一年后,这时我发现再写博客,不在是为了找一份工作,已经变成一种习惯!一种成长型心态! 接着一年、两年

    2024年02月10日
    浏览(39)
  • 我的创作纪念日(128天)

    今天,我像往常一样打开CSDN 网站,随即弹出的两则官方私信: 我这才意识到,从去年的11月27日到现在,时光荏苒,已是128天之久。 下面我向各位看分享一下我在CSDN创作的经历和收获,以及我的一些个人感受。(ps:故事有点长严`( ﹏ )′) 我最早接触CSDN社区,起始于201

    2023年04月22日
    浏览(42)
  • 【人生历程】我的创作纪念日

    目录 与编程不得不说的爱恨情仇 在csdn的收获: 与csdn的日常 在平凡的日子偶然的成就感: 对未来的憧憬: 今天是2023.4.8号,早上的刚刚参加完蓝桥杯,下午看到csdn官方的活动,心血来潮写下以下内容,如有不适或者错误请见谅。 在2021我成功摆脱了高中生这个身份,我称为

    2023年04月09日
    浏览(42)
  • 我的创作纪念日(730天)

    不知不觉来到CSDN已经730天了,这两年来我收获丰富,从原本的只是从CSDN获取知识,到现在的传播知识,我感觉受益良多,一年多的沉淀,让我在这三个月中绽放,粉丝也从原本的两位数到现在的四千+,学习中记笔记是我养成的习惯,自己总结的东西总觉得很适合自己记忆。

    2024年01月17日
    浏览(45)
  • 我的创作纪念日——创作历程,机缘,与成就

    作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。   座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 目录  写在前面  一.机缘 二.收获 三.日常 四.成就  五.憧憬与规划 六.分享 大家好~我是网络豆,不知不觉已经在CSDN创作有一年

    2024年02月09日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包