动态内存的管理

news2024/11/15 19:28:38

1.为什么要有动态数组呢

int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间

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

  • 空间开辟大小是固定的
  • 数组在申明的时候,必须指定数组的长度,数组空间一旦确定了大小不能调整

对于空间的开辟,固定的空间大小有时候不能满足我们的需求。这个时候我们就需要自己开辟一段空间。

2.malloc与free

malloc函数

C语言为我们提供了一个动态内存开辟的函数:malloc

void* malloc (size_t size);
这个函数向内存申请⼀块连续可用的空间,并返回指向这块空间的指针。
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个 NULL 指针,因此malloc的返回值一定要做检查。
返回值的类型是void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自    己 来决定。
如果参数 size为0,malloc的行为是标准是未定义的,取决于编译器。
int main()
{
	int* p = (int*)malloc(40);
	//这里开辟了一段40字节的空间
	return 0;
}

free函数

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:
void free (void* ptr);
free函数用来释放动态开辟的内存。
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
malloc和free都声明在 stdlib.h 头文件中。
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* ptr = NULL;
	ptr = (int*)malloc(10 * sizeof(int));
	if (NULL != ptr)//判断ptr指针是否为空
	{
		int i = 0;
		for (i = 0; i < 10; i++)
		{
			*(ptr + i) = 0;
		}
	}
	free(ptr);//释放ptr所指向的动态内存
	ptr = NULL;
	return 0;
}

注:malloc常常与free搭配,使用malloc开辟空间,执行完程序后需要使用free进行空间的释放

 3.calloc和realloc

C语言还提供了⼀个函数叫 calloc , calloc 函数也用来动态内存分配。原型如下:

这里我们就要学习到malloc的亲兄弟了

calloc函数

void* calloc (size_t num, size_t size);
  • 函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
  • 与函数malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为全0。
我们可以利用调试进行监视:
VS实用调试技巧-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Asuku_/article/details/137396302
举个例子:
#include <stdio.h>
#include <stdlib.h>

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

我们会发现输出结果全为0;

所以如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务。

relloc函数

  • realloc函数的出现让动态内存管理更加灵活。
  • 有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们⼀定会对内存的大小做灵活的调整。那realloc函数就可以做到对动态开辟内存大的调整。
函数原型如下:
void* realloc (void* ptr, size_t size)
  • ptr 是要调整的内存地址
  • size 调整之后新大小
  • 返回值为调整之后的内存起始位置。
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
  • realloc在调整内存空间的是存在两种情况:
    情况1:原有空间之后有足够大的空间
当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
      ◦ 情况2:原有空间之后没有足够大的空间
当是情况2的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找⼀个合适大小的连续空间来使用。这样函数返回的是⼀个新的内存地址

常见的动态内存的错误

对NULL指针的解引用操作

void test()
 {
 int *p = (int *)malloc(INT_MAX/4);
 *p = 20;//如果p的值是NULL,就会有问题
 free(p);
 }

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

void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;//当i是10的时候越界访问
}
free(p);
}

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

void test(){

 int a = 10;
 int *p = &a;
 free(p);<-
 
}    

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

void test()
 {
 int *p = (int *)malloc(100);
 p++;    //每次加1,p的地址都会发生变化
 free(p);//p不再指向动态内存的起始位置
 
 }

对同一块动态内存多次释放

void test()
 {
 int *p = (int *)malloc(100);
 free(p);
 free(p);//重复释放
 }

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

void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}

以上为容易出现的问题!!!

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

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

相关文章

【AI自媒体制作】【AI工具】天工AI

链接&#xff1a;天工AI 目前chatgpt3.5已经免费&#xff0c;很多AI平台都可以进行一定层度的白嫖&#xff0c;对于个人开发者是一件好事&#xff0c;有些会员就没必要充值了。 天工AI是比较常见的AI工具了&#xff0c;可以识别图片、智能问答、生成图片等。当然对于一个程序员…

关于电商独立站搭建中电商API数据采集接口的应用

搭建供应链系统时&#xff0c;您可能需要与电商平台进行集成&#xff0c;以实现订单管理、库存同步、物流跟踪等功能。以下是一些常见的电商接口&#xff0c;可以帮助您构建供应链系统&#xff1a; 1. **淘宝开放平台接口**&#xff1a;淘宝开放平台提供了丰富的接口&#xff…

上位机图像处理和嵌入式模块部署(树莓派4b和驱动的编写)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 树莓派4b上面还支持驱动代码的编写&#xff0c;这是我没有想到的。这里驱动&#xff0c;更多的是一种框架的编写&#xff0c;不一定是编写真正的驱…

Selenium web自动化测试环境搭建

Selenium web自动化环境搭建主要要经历以下几个步骤&#xff1a; 1、安装python 在python官网&#xff1a;Welcome to Python.org&#xff0c;根据各自对应平台如&#xff1a;windows&#xff0c;下载相应的python版本。 ​ 下载成功后&#xff0c;点击安装包&#xff0c;一直…

排序之插入排序:从斗地主到插入排序

目录 1.斗地主如何摸牌 2.从摸牌想到插入排序 3.完成插入排序 4.结束语 1.斗地主如何摸牌 不知道各位是否玩过几乎人人都玩过的斗地主游戏呢&#xff1f;相必各位或多或少都玩过一点&#xff0c;再没玩过也看别人打过。今天博主就将从这个游戏为大家讲解我们的插入排序。 在…

shell编写

运算符 echo 打印 unset 删除 [ boolean表达式 ] 注意中括号中有两个空格&#xff0c;两个空格中添加表达式 0为true 1为false $?查看结果 -ge 大于等于 lt小于 le小于等于 eq等于 ne不等于 格式& | [ 表达式 ] -o是或者or的意思 -a是and的意思 &#xff01…

访问学者申请的成功经验

在申请成为访问学者时&#xff0c;经验是至关重要的。下面知识人网小编将介绍一些可以帮助您成功申请的经验和技巧。 首先&#xff0c;了解目标机构或大学的研究方向和需求是非常重要的。在申请之前&#xff0c;仔细研究该机构的学术项目、研究成果以及教授的专业领域&#xff…

kaggle 泰坦尼克号2 得分0.7799

流程 导入所要使用的包引入kaggle的数据集csv文件查看数据集有无空值填充这些空值提取特征分离训练集和测试集调用模型 导入需要的包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarni…

Redis 逻辑过期策略设计思路

引言&#xff1a; 当我们平常使用Redis缓存的时候&#xff0c;会出现一种场景&#xff0c; redis的key到过期时间了&#xff0c;总是需要到数据库里面去查一遍数据再set回redis&#xff0c;这个时候如果数据库响应比较慢&#xff0c;那么就会造成用户等待&#xff0c;如果刚好…

python爬虫小案例——汽车之家

本篇文章是使用bs4中的BeautifulSoup和requests解析网页和获取数据&#x1f451;&#x1f31f; 文章目录 &#x1f31f;前言一、&#x1f349;bs4中的BeautifulSoup二、&#x1f349;bs4的语法三、&#x1f349;内容实践1. 确定想要爬取的内容2. 分析网页3. 获取数据分析 &…

【ThinkPHP框架教程·Part-02】开发规范和目录结构

文章目录 一、开发规范1、目录和文件的规范2、函数和类、属性命名规范3、常量与配置的规范4、数据表和字段的规范 二、目录结构1、单应用模式目录结构图&#xff08;默认&#xff09;2、多应用模式目录结构图&#xff08;自定义&#xff09;3、仅允许public目录对外访问4、其他…

软考141-上午题-【软件工程】-杂题+小结

一、杂题 真题1&#xff1a; 真题2&#xff1a; 真题3&#xff1a; 真题4&#xff1a; 真题5&#xff1a; 真题6&#xff1a; 真题7&#xff1a; 真题8&#xff1a; 真题9&#xff1a; 真题10&#xff1a; 真题11&#xff1a; 真题12&#xff1a; 真题13&#xff1a; 真题14&a…

4.20 IO流

IO流结构 InputStream&#xff08;字节输入流&#xff09; public static void main(String[] args) {// byteInputStream();// byteInputStream1();// byteInputStream2();byteInputStream3();}// 使用字节流时对于中文汉字基本都会出现乱码问题&#xff0c;因此对中文乱码问…

ccfcsp201312-2 ISBN号码

注意&#xff1a;50分 -- u10&#xff0c;最后一位为X 代码&#xff1a; #include <bits/stdc.h> using namespace std; string s; int a[12]; int main() {cin >> s;a[1] s[0] - 0;a[2] s[2] - 0;a[3] s[3] - 0;a[4] s[4] - 0;a[5] s[6] - 0;a[6] s[7] - …

常见排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序)

一.排序的概念 1.排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作 2.稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排…

【WinForm】背景图片绘制无效果的解决方法

例如&#xff0c;在WinForm桌面的窗体设置了背景图片&#xff0c;尝试从上方绘制时却未能产生预期效果, 就是从背景图片上面绘制却没有效果。 文章目录 示例改进 下面是一个在窗体背景上绘制圆形边框的示例。 示例 修改前&#xff0c;代码如下 var gCtx Graphics.FromImage…

vulfocus靶场redis 未授权访问漏洞之CNVD-2015-07557

目标系统的权限不够redis用户无法写计划任务和公钥&#xff0c;而且也没有开放ssh端口。 主从复制getshell&#xff0c;写入恶意的so文件达到执行系统命令的目的。 github上有一键可以利用的脚本 https://github.com/n0b0dyCN/redis-rogue-server.git 利用条件&#xff1a;需…

polkit服务启动失败

使用systemctl 命令报错 Authorization not available. Check if polkit service is running or see debug message for more information. 查看polkit状态是失败的状态&#xff0c;报缺少libstdc.so.6 systemctl status polkit 需要安装libstdc.so.6库 先加载所有安装包 …

深入剖析Spring框架:循环依赖的解决机制

你好&#xff0c;我是柳岸花开。 什么是循环依赖&#xff1f; 很简单&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象。 在Spring中&#xff0c;一个对象并不是简单new出来了&#xff0c;而是会经过一系列的Bean的生命周期&#xff0c;就是因为Bean的生命周期所…

测绘管理与法律法规 | 测绘资质分类分级标准 | 学习笔记

目录 1. 申请条件 2.审批程序 3.专业技术人员的特殊规定 1. 申请条件 法人资格&#xff1a;申请单位必须具有法人资格。 专业技术人员&#xff1a;需拥有与测绘活动相适应的测绘专业技术人员和相关专业技术人员。 技术装备&#xff1a;具备与测绘活动相适应的技术装备和设…