我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C语言的动态内存管理的深入了解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C语言的动态内存管理的深入了解

一、动态内存分配

  • (1)用malloc类的函数分配内存;
  • (2)用这些内存支持应用程序;
  • (3)用free函数释放内存。

内存的简答来说的三大操作:分配----使用----释放

内存管理指的是:分配— ----释放

我们编写的程序代码:使用

程序本质上就是处理数据,数据信息需要存放在内存里,就是用二极管表示的开断表示二进制数,进一步用二进制数表示万物:如音乐、文字、视频、图片、等等各种资源。

分配–释放:为了更好的利用和回收内存资源,最大程度的发挥计算资源,统一操作系统来调度

动态内存分配其实就要谈到自动内存分配

自动分配:内存其实就是我们在编程文件里定义的变量实际在运行时映射的内存,这部分变量的内存都是由系统自动管理(分配-释放)。函数体(或者语句块)内的变量都是分布在函数  里面,运行时就会把这个帧插入到函数运行栈里,内存这些都由系统分拨,运行完就出栈,内存也被操作系统回收,一致到主函数出栈,程序退出。

动态分配:就是我们自己手动申请操作系统给我们程序分配的内存,内存区域主要在于  上,这部分资源是我们手动申请和回收的。分配到的资源是我们来操作、存放数据的地方。

实际上我们定义的变量最后也会被翻译为地址,都是通过寻址来操作变量的值(可以去看看汇编语言)

#include <stdio.h>
#include <stdlib.h>
 int main(void)
{
	int*pi=(int*)malloc(sizeof(int));
	*pi=5;
	printf("*pi:%d\n",*pi);
	free(pi);
 	return 0;
}

在这里插入图片描述

注意点

int *pi=(int)malloc((4));

  • 然而,依赖于系统所用的内存模型,整数的长度可能会发生变化。可移植的方法是使用sizeof操作符,这样不管程序在哪里运行都会返回正确的长度。
  • 使用(int)malloc(number * (sizeof(int)));*

二、动态内存分配函数

有几个内存分配函数可以用来管理动态内存,虽然具体可用的函数取决于系统,但大部分系统的stdlib.h头文件中都有如下函数:

malloc()

realloc()

calloc()

函数描述
malloc从堆上分配内存
realloc在之前分配的内存块的基础上,将内存重新分配为更大或者更小的部分
calloc从堆上分配内存并清零

1、malloc()

malloc函数从堆上分配一块内存,所分配的字节数由该函数唯一的参数指定,返回值是void指针,如果内存不足,就会返回NULL。此函数不会清空或者修改内存。

声明:voidmalloc(size_t);

  • (1)从堆上分配内存;
  • (2)内存不会被修改或是清空;
  • (3)返回首字节的地址。

实例用法int* pi=(int*)malloc(sizeof(int));

因为当malloc无法分配内存时会返回NULL,在使用它返回的指针之前先检查NULL是不错的做法,如下所示:

int*pi=(int*)malloc(sizeof(int));
if(pi!=NULL)
{
	//指针没有问题
}else
{
	//无效的指针
}
  • (4)静态、全局指针和malloc

初始化静态或全局变量时不能调用函数。下面的代码声明一个静态变量,并试图用malloc来初始化:

*static int pi = malloc(sizeof(int));

这样会产生一个编译时错误消息,全局变量也一样。

对于静态变量,可以通过在后面用一个单独的语句给变量分配内存来避免这个问题。但是全局变量不能用单独的赋值语句,因为全局变量是在函数和可执行代码外部声明的,赋值语句这类代码必须出现在函数中:

static int *pi;
pi = malloc(sizeof(int)); 

2、realloc()

声明:void *realloc(void *ptr,size t size);

realloc函数返回指向内存块的指针。该函数接受两个参数,第一个参数是指向原内存块的指针,第二个是请求的大小。重新分配的块大小和第一个参数引用的块大小不同。返回值是指向重新分配的内存的指针。

第一个参数第二个参数行为
同malloc
非空0原内存块被释放
非空比原内存块小利用当前的块分配更小的块
非空比原内存块大要么在当前位置要么在其他位置分配更大的块

在这里插入图片描述

堆管理器可以重用原始的内存块,且不会修改其内容。不过程序继续使用的内存超过了所请求的8字节。也就是说,我们没有修改字符串以便它能装进8字节的内存块中。在本例中,我们本应该调整字符串的长度以使它能装进重新分配的8字节。实现这一点最简单的办法是将NUL赋给地址507。实际使用的内存超出分配的内存不是个好做法,应该避免。

在这里插入图片描述

3、calloc()

calloc函数在申请内存时会清空内存【清空内存的意思是将其内容置为二进制0】

声明: void *calloc(size_t numElements,size_t elementSize);

calloc函数会根据numElements和elementSize两个参数的乘积来分配内存,并返回一个指向内存的第一个字节的指针。如果不能分配内存,则会返回NULL。此函数最初用来辅助分配数组内存。

如果numElements或elementSize为0,那么calloc可能返回空指针。如果calloc无法分配内存就会返回空指针,而且全局变量errno会设置为ENOMEM(内存不足),这是POSIX错误码,有的系统上可能没有。

三、用free函数释放内存

有了动态内存分配,程序员可以将不再使用的内存返还给系统,这样可以释放内存
留作他用。通常用free函数实现这一点,该函数的原型如下:

声明: void free(void *ptr);

指针参数应该指向由malloc类函数分配的内存的地址,这块内存会被返还给堆。尽管指针仍然指向这块区域,但是我们应该将它看成指向垃圾数据。稍后可能重新分配这块区域,并将其装进不同的数据。

在这里插入图片描述

要点

  • 释放含义:指的是释放堆上的申请内存,其实就是告诉堆管理器,这个资源我不用了,可以回收了
  • 本地还是保留了之前申请内存的地址,这个地址我们应该避免去使用,也就是置这个指针为NULL
  • 不能再去接引已释放资源指针的值
  • 不能重复多次释放指针指向的内存(free)

四、迷途指针

如果内存已经释放,而指针还在引用原始内存,这样的指针就称为迷途指针。迷途指针没有指向有效对象,有时候也称为过早释放
迷途指针带来的问题:

  • 如果访问内存,则行为不可预期;
  • 如果内存不可访问,则是段错误;
  • 潜在的安全隐患。

造成的原因:

  • 访问已释放的内存;
  • 返回的指针指向的是上次函数调用中的自动变量;
//第一种情况
int*pi = (int*)malloc(sizeof(int));
printf("*pi:%d\n",*pi);
free(pi);
*pi = 10;
 //第二种情况
int*p1 = (int*)malloc(sizeof(int));
*p1 = 5;
int* p2;
p2 = p1;
free(p1);
*p2 = 10;//迷途指针
 //第三种情况

int *pi;
int tmp = 5;
pi = &tmp;
//这里pi变成了迷途指针
foo();

在这里插入图片描述

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!      

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C语言的动态内存管理的深入了解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解C语言中的动态内存管理

对于数据的存储我们可以静态存储,也可以动态存储,两种方式都有自己特有的好处,这篇文章教我们如和进行动态的数据存储!!!!感兴趣的小伙伴可以跟随小编一起学习一下
2022-12-12

深入了解Go语言内存管理的底层机制

Go语言的内存管理是基于垃圾回收的机制,它使用了一个称为Go垃圾回收器的组件来自动管理内存的分配和释放。Go垃圾回收器使用了一个基于标记-清除的算法来识别和回收不再使用的内存。在Go语言中,内存管理的核心原则是零分配(zero alloca
2023-10-08

C语言动态内存管理的方法是什么

本文小编为大家详细介绍“C语言动态内存管理的方法是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言动态内存管理的方法是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.为什么需要动态内存分配关于这个
2023-06-29

C语言的动态内存管理是什么意思

这篇文章将为大家详细讲解有关C语言的动态内存管理是什么意思,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、动态内存分配(1)用malloc类的函数分配内存;(2)用这些内存支持应用程序;(3)用free
2023-06-29

C语言中动态内存管理的示例分析

这篇文章主要介绍了C语言中动态内存管理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是动态内存分配我们都知道在C语言中,定义变量的时候,系统就会为这个变量分配内
2023-06-25

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录