C语言——动态内存分配

        前言:通过前面的学习,我们知道C语言中在内存中开辟空间的方法有:变量和数组。既然拥有了开辟空间的方法,我们为什么还要学习动态内存分配呢?

int val = 20;  //在内存中开辟四个字节的空间
int arr[10] = { 0 }; //在内存中开辟四十个字节的连续空间

        变量和数组确实可以在内存中开辟空间,但它们也有一些不足的点 :①、开辟的空间大小是固定的,②、数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。但很多时候我们无法一开始就知道程序到底需要多少内存,使用数值和变量当程序需要的内存变大时,数组和变量开辟的空间是无法变大的,满足不了程序的需求,动态内存正是在这样的基础上诞生。

        一、动态内存函数:

1.1malloc和free:

1.1.1mall函数语法和使用:

malloc函数语法:

 malloc函数作用:动态开辟内存,可以向内存申请一块连续可以的空间,并返回指向这块空间的指针。

malloc开辟空间指针返回注意点:

        如果间开辟成功时,返回指向该空间的指针。
        如果开辟空间失败,返回一个NULL指针。
        malloc函数的返回值类型为:void* 类型,malloc函数不会指定开辟空间的类型,具体类型由使用者决定。

函数头文件:        stdlib.h 

C++plus地址:malloc - C++ 参考 (cplusplus.com)

int main()
{int* p = (int*)malloc(40);return 0;
}

空间打印演示:

int main()
{int* p =(int*) malloc(40);//判断空间是否开辟成功if (p == NULL){perror("malloc"); //开辟失败报错return 1;}//开辟成功int i = 0;for ( i = 0; i < 10; i++){printf("%d\n",*(p+1)); //以十进制打印指针内容} return 0;
}

代码里面的 int* p =(int*) malloc(40); 与int arr[10] 具有相同的效果,int类型为4个字节,10个int类型的数据刚好大小为40个字节。

malloc函数开辟内存块的大小,以字节为单位。是无符号整数类型(size_t);

malloc申请的空间在内存中的存储位置:

malloc申请空间后 :

malloc 申请到空间后,直接返回的是这快空间的起始地址,不会初始化该空间的内容。所以是上面的代码打印过程中,我们会发现打印的值为一些不正常的数字。

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;}for ( i = 0; i < 10; i++){printf("%d ",*(p+i));}free(p);return 0;
}

        上面代码中最后在完成打印数据时,书写了free(p); 的语句,当我们将它去掉,在VS中就行打印时,视乎也没有什么特别大的问题,但这里却必须要使用它,这是为什么呢?

1.1.2 free函数:

free函数语法:

void free (void* ptr);

        free函数的作用:动态内存的释放和回收。

free函数注意点:

        ①、如果ptr指向的空间不是动态开辟的,那么函数free的行为就是未定义行为。

        ②、如果参数ptr是NULL指针,则函数什么事情都不用做。

函数头文件:stdlib.h

 C++plus地址:free - C++ 参考 (cplusplus.com)

1.2calloc和realloc函数:

        前面我们学习了malloc同态内存开辟,calloc函数的作用也是进行动态内存开辟的.

calloc函数语法:

 函数功能:开辟num个大小为size的元素开辟一块空间,并且会将空间的每个字节初始化为0。

int main()
{int* p = (int*)calloc(10, sizeof(int)); //calloc动态空间开辟,大小40字节if (p == NULL){perror("calloc"); //错误检测}//打印数据int i = 0;for ( i = 0; i < 10; i++){printf("%d ",p[i]);}free(p);return 0;
}

realloc函数语法:

         ptr 是要调整的内存地址,size调整之后新大小。

        realloc的返回值为调整后的内存起始位置。

        realloc函数不仅会调整原内存空间大小,还会将原来内存中的数据移动到新的空间。

realloc函数调整内存空间的两种情况:

        ①、原有空间之后有足够大的空间。

直接在原有内存之后追加空间,原空间的数据不变。 

        ②、原有空间之后没有足够大的空间。

第二种情况时,会开辟新的空间,并且将就的空间中的数据拷贝到新的空间中,释放旧的空间,并且返回新空间的地址。 

函数使用代码:

int main()
{int* p = (int*)malloc(40);if (p == NULL){perror("malloc");return 1;}//初始化为1~10int i = 0;for ( i = 0; i < 10; i++){p[i] = i + 1;}//扩展空间int* ptr = realloc(p,80);if (ptr != NULL){p = ptr;}return 0;
}

1.3常见的动态内存错误:

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

int main()
{int* p = (int*)malloc(INT_MAX/4);*p = 20;free(p);
}

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

int main()
{int i = 0;int* p = (int*)malloc(10*sizeof(int));if (NULL == p){perror(malloc);}for ( i = 0; i <= 10; i++){*(p+i) = i;}free(p);
}

3、对非动态开辟内存使用free释放:

int main() 
{int a = 10;int* p = &a;free(p);
}

4、同一块空间多次释放: 

int main()
{int i = 0;int* p = (int*)malloc(10*sizeof(int));if (NULL == p){perror(malloc);}for ( i = 0; i < 10; i++){*(p+i) = i;}free(p);p = NULL;free(p); //错误地方。return 0;
}

5、动态内存开辟忘记释放:(内存泄漏)

int main()
{int* p =(int*) malloc(40);//判断空间是否开辟成功if (p == NULL){perror("malloc"); //开辟失败报错return 1;}//开辟成功int i = 0;for ( i = 0; i < 10; i++){printf("%d\n",*(p+1)); //以十进制打印指针内容} return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/745619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【金三银四】掌趣科技24.3.7 H项目 服务端开发笔试题

考试题型&#xff1a; 不定项选择题 10 道 &#xff0c; 填空题 10 道 &#xff0c; 问答题 2 道 &#xff0c; 编程题 4 道 目录 不定项选择题 10 道填空题 10 道问答题 2 道编程题 4 道 不定项选择题 10 道 在TCP协议中&#xff0c;发送方的窗口大小是由两个关键因素共同决定…

鸿蒙 Harmony 初体验

前言 看现在网上传得沸沸扬扬的鸿蒙&#xff0c;打算弄个 hello world 玩一下, 不然就跟不上时代的发展了 环境安装 我的环境 Windows 11 家庭中文版HarmonyOS SDK (API 9)DevEco Studio (3.1.1 Release)Node.js (16.19.1) 开发IDE下载 官方下载链接 配置 nodejs 这里帮…

Opencascade基础教程(9):切换视图

1、切换视图 1、1 增加视图切换按钮&#xff0c;并添加消息响应函数。 void COCCDemoView::OnButtonFrontview() {//前视图m_View->SetProj(V3d_Yneg);m_View->FitAll(); }void COCCDemoView::OnButtonRearview() {//后视图m_View->SetProj(V3d_Ypos);m_View->Fit…

【华为Datacom数通认证】HCIA-HCIP-HCIE

华为认证课程概述 华为认证是华为技术有限公司(简称"华为")基于"平台生态"战略&#xff0c;围绕"云-管-端"协同的新ICT技术架构&#xff0c;打造的业界覆盖ICT领域最广的认证体系&#xff0c;包含"ICT技术架构认证"、"ICT开发者…

学习JAVA的二十二天(基础)

目录 网络编程 三要素&#xff1a; IP InetAddress类 端口号 协议 UDP协议 TCP协议 前言&#xff1a;学习JAVA的第二十一天&#xff08;基础&#xff09;-CSDN博客 网络编程 在网络通信协议下&#xff0c;不同计算机上运行的程序,进行的数据传输。 三要素&#xff1a;…

installation of package ‘RDocumentation’ had non-zero exit status

installation of package ‘RDocumentation’ had non-zero exit status Warning in install.packages :installation of package ‘httr’ had non-zero exit status Warning in install.packages :installation of package ‘openssl’ had non-zero exit status 由于项目需…

蓝桥杯(1):python排序

1 基础 1.1 输出 1.1.1 去掉输出的空格 print("Hello","World",123,sep"") print("hello",world,123,sep) print(hello,world,123) #输出结果 #HelloWorld123 #helloworld123 #hello world 123 1.1.2 以不同的方式结尾 print(&quo…

Ubuntu Flask 运行 gunicorn+Nginx 部署

linux Ubuntu 下运行python 程序出现killed 原因&#xff1a;CPU或内存限制&#xff1a;在华为云上&#xff0c;你可能有CPU或内存使用的限制。例如&#xff0c;如果你使用的是一个固定大小的实例&#xff0c;那么超过该实例的CPU或内存限制可能会导致进程被杀死。 参考&am…

Python Web开发记录 Day10:Django part4 靓号管理与优化

名人说&#xff1a;莫道桑榆晚&#xff0c;为霞尚满天。——刘禹锡&#xff08;刘梦得&#xff0c;诗豪&#xff09; 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、数据库准备2、靓号列表3、新建靓号4、编辑靓…

Vue手写模拟步骤条

效果图&#xff1a; 如果要使用element的步骤条就需要强行修改样式&#xff0c;参考之前的那篇步骤条。这里我采用手写div 代码&#xff1a; 思路是给最外层的div一个左边框&#xff0c;给里面的step-item设置左边框为图片&#xff0c;通过定位来移动。 <div class"m…

Canal实现mysql与缓存同步

什么是Canal Canal是阿里巴巴旗下的一款开源项目, 基于java开发. Canal是基于mysql的主从同步来实现的. github地址: https://github.com/alibaba/canal Canal把自己伪装成MySQL的一个slave节点, 从而监听master的binary log变化. 再把得到的变化信息通知给Canal的客户端, 进而…

个人简历主页搭建系列-02:github 仓库作为联系方式

这篇文章暂时没有开始正式搭建网站。首先是最重要的注意事项&#xff1a;隐私。 真实姓名如果大家自己不介意的话其实我觉得还好&#xff0c;现在在互联网上想扒个姓名挺简单的&#xff0c;而且很多人都实名上网hh&#xff08;比如我的几位田径队学弟笑&#xff09;。 电话&a…

小程序学习3 goods-card

pages/home/home home.wxml <goods-listwr-class"goods-list-container"goodsList"{{goodsList}}"bind:click"goodListClickHandle"bind:addcart"goodListAddCartHandle"/> <goods-list>是一个自定义组件&#xff0c;它具…

[抽象]工厂模式([Abstract] Factory)——创建型模式

[抽象]工厂模式——创建型模式 什么是抽象工厂&#xff1f; 抽象工厂模式是一种创建型设计模式&#xff0c;让你能够保证在客户端程序中创建一系列有依赖的对象组时&#xff0c;无需关心这些对象的类型。 具体来说&#xff1a; 对象的创建与使用分离&#xff1a; 抽象工厂模…

信号与系统学习笔记——信号的分类

目录 一、确定与随机 二、连续与离散 三、周期与非周期 判断是否为周期函数 离散信号的周期 结论 四、能量与功率 定义 结论 五、因果与反因果 六、阶跃函数 定义 性质 七、冲激函数 定义 重要关系 作用 一、确定与随机 确定信号&#xff1a;可以确定时间函数…

uniapp移动端 IOS系统下无法与webview通信

不知道有没有人遇到过这个问题 我的页面嵌套了一个webview&#xff08;文件位于项目的hybrif/html&#xff09;目录下 使用evalJS与webview进行通信 代码如下 在安卓里运行是没问题的&#xff0c;但在苹果手机上一直无法通信 连接真机&#xff0c;打印evalJS是个方法&#xf…

C语言中内存函数的使用

memcpy函数的使用和模拟实现 memcpy的使用 函数使用说明&#xff1a; • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇到 \0 的时候并不会停下来。 • 如果source和destination有任何的重叠&#xff0c;复制的结…

【python】centos 8新装python3.10.0

1.python源码包准备 2.gcc环境安装 如果系统已具备&#xff0c;可以略过。 有的已经自带了gcc&#xff0c;但是如果编译时启动优化的话&#xff0c;如果gcc版本过老就必须要升级。 3.make环境安装 如果系统已具备&#xff0c;可以略过。 4.更新openssl版本&#xff08;很重…

C# 根据两点名称,寻找两短路程的最优解,【有数据库设计,完整代码】

前言 如果我们遇到路径问题&#xff0c;可以使用点点连线&#xff0c;给定一个点&#xff0c;可以到达另外几个点&#xff0c;寻找最优解 例&#xff1a;如下图所示&#xff0c;如果要从A1-C1,可以有三条路 1.A1-B1-C1 2.A1-B2-C1 3.A1-B3-C1 最优解肯定是A1-B1-C1&#xff0c…

Java代码审计安全篇-XXE(XML外部实体注入)漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计&#xff0c;记录自己的学习过程&#xff0c;还希望各…