c语言之动态内存管理及常见错误分析,柔性数组,内存划分

news2024/11/18 22:32:39

目录

 前言

一:malloc,calloc,realloc,free四大函数

1.malloc

2.free 

3.calloc

4.realloc 

二:常见错误分析 

1.malloc返回值不检查直接使用

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

3.对非动态开辟空间free 

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

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

6.对动态内存空间未释放--内存泄漏 

三:柔性数组 

1.定义

2.特点 

3.使用 

4.内存分配规则 

5.非柔性数组方法 

6.柔性数组的优势 

四:c/c++中程序内存区域划分

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧

 前言

对于c语言的动态内存管理是在原先定义数组时,数组的大小被指定,无法修改,可能造成空间的浪费或者空间不够造成越界访问,所以在此基础上提出用malloc,calloc,realloc,free四大函数来维护,自己开辟想要的空间大小,并自己释放,而柔性数组也是用来动态开辟空间的,接下来一一介绍

一:malloc,calloc,realloc,free四大函数

1.malloc

1.这个函数是用来向内存申请 一块连续可用的空间,并返回指向这块空间的指针

2.如果开辟成功,返回一个指向开辟好空间的指针

3.如果开辟失败,则返回一个NULL,因此malloc必须做返回值检查

4.返回类型为void*,需要自己根据需要调整

5.如果size为0,这种行为是未定义的,取决于编译器

#include <stdio.h>
int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  if(p==NUL)
 {
   perror("malloc fail");
   return ;
 } 
 int i=0;
  for(i=0;i<5;i++)
  {
    *(p+i)=i+1;
  }
  for(i=0;i<5;i++)
  { 
    printf("%d ",p[i]);
  }

  free(p);//动态开辟的空间必须释放
  p=NULL;
}

2.free 

用来对动态开辟的内存空间释放和回收的

1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的⾏为是未定义的。

2.如果参数 ptr 是NULL指针,则函数什么事都不做

3.必须是动态开辟空间的起始地址,所以对于动态内存申请过程中有p++这种如果在释放时只释放部分空间,这种行为是不允许的,释放应该是整体全部释放

4.free释放完空间后,需要手动将指针置为NULL 

3.calloc

1.calloc也是用来动态内存分配的

2.函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。

3.与malloc函数的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0.

4.如果我们要对动态申请的内存空间要求初始化时,就是用calloc函数

 

4.realloc 

1.有时对于动态开辟的空间 太小或者太大,我们需要做出调整,这时就用realloc函数来调整动态开辟内存大小

2.ptr是要调整的内存地址,size是调整之后新大小,返回值是调整之后的内存起始地址

3.realloc在调整内存空间的两种情况

4.当ptr为NULL时,realloc和malloc作用一样

原地扩容

异地扩容

 

使用

 

 

二:常见错误分析 

1.malloc返回值不检查直接使用

#include <stdio.h>
int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  *p=20;//如果指针p为空,则直接对空指针解引用错误
   free(p);
}

正确的应该检查malloc的返回值,不为空再进行相应操作

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

int main()
{
  int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
    perror("malloc fail");
    return ;
 }
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);
 return 0;
}

3.对非动态开辟空间free 

int main()
{ 
  int a=10;
  int*p=&a;
  free(p);//对非动态开辟空间进行free直接出错
  return 0;
}

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

int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  if(p==NUL)
 {
    perror("malloc fail");
    return ;
 }
  p++;
  free(p);//这样只会释放一部分
}

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

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

6.对动态内存空间未释放--内存泄漏 

int main()
{
  int *p = (int *)malloc(100);
  if(NULL != p)
   {
     *p = 20;
   }
   //未释放动态开辟空间,内存泄漏
   return 0;
}

三:柔性数组 

1.定义

结构体中最后一个成员是数组,但数组没有指定大小

struct S
{
  int n;
  int a[];//或者int a[0];
};

2.特点 

 1.结构中的柔性数组成员前⾯必须⾄少⼀个其他成员

2.sizeof 返回的这种结构⼤⼩不包括柔性数组的内存

3.包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的⼤ ⼩,以适应柔性数组的预期⼤⼩

3.使用 

4.内存分配规则 

就如上面用malloc来开辟空间时,内存上为

5.非柔性数组方法 

#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{
 int i;
 int *p_a;
}type_a;

int main()
{
 type_a *p = (type_a *)malloc(sizeof(type_a));
 p->i = 100;
 p->p_a = (int *)malloc(p->i*sizeof(int));
 
 //业务处理
 for(i=0; i<100; i++)
 {
 p->p_a[i] = i;
 }
 
 //释放空间
 free(p->p_a);
 p->p_a = NULL;
  free(p);
  p=NULL;
  return 0;
}

6.柔性数组的优势 

1.方便内存释放

2.有利于提高访问速度

四:c/c++中程序内存区域划分

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

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

相关文章

QAuth 2.0

OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务&#xff0c;通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源&#xff0c;或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解&#xff0c;可以想象OAuth2.0就是在用户资源和第…

多路转接-epoll/Reactor(2)

epoll 上次说到了poll&#xff0c;它存在效率问题&#xff0c;因此出现了改进的poll----epoll。 目前epoll是公认的效率最高的多路转接的方案。 快速了解epoll接口 epoll_create&#xff1a; 这个参数其实已经被废弃了。 这个值只要大于0就可以了。 这是用来创建一个epoll模…

用友U9 存在PatchFile.asmx接口任意文件上传漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 用友U9是由中国用友软件股份有限公司开发的一款企业…

FJSP:狐猴优化算法(Lemurs Optimizer,LO)求解柔性作业车间调度问题(FJSP),提供MATLAB代码

一、柔性作业车间调度问题 柔性作业车间调度问题&#xff08;Flexible Job Shop Scheduling Problem&#xff0c;FJSP&#xff09;&#xff0c;是一种经典的组合优化问题。在FJSP问题中&#xff0c;有多个作业需要在多个机器上进行加工&#xff0c;每个作业由一系列工序组成&a…

Linux(Ubuntu)中创建【samba】服务,用于和Windows系统之间共享文件

目录 1.先介绍一下什么是Samba 2.安装&#xff0c;配置服务 安装 配置&#xff08;smb.conf&#xff09; 配置用户 3.出现的问题&#xff08;Failed to add entry for user XXXX&#xff09; 4.创建文件夹 5.windows访问 1.先介绍一下什么是Samba Samba是一个开源的软…

HTML5.Canvas简介

1. Canvas.getContext getContext(“2d”)是Canvas元素的方法&#xff0c;用于获取一个用于绘制2D图形的绘图上下文对象。在给定的代码中&#xff0c;首先通过getElementById方法获取id为"myCanvas"的Canvas元素&#xff0c;然后使用getContext(“2d”)方法获取该Ca…

剑指Offer题目笔记26(动态规划的基础知识)

面试题88&#xff1a; 问题&#xff1a; ​ 一个数组cost的所有数字都是正数&#xff0c;它的第i个数字表示在一个楼梯的第i级台阶往上爬的成本&#xff0c;在支付了成本cost[i]之后可以从第i级台阶往上爬1级或2级。请计算爬上该楼梯的最少成本。 解决方案一&#xff1a;&…

【简单讲解下epoll】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Day:004(1) | Python爬虫:高效数据抓取的编程技术(数据解析)

数据解析-正则表达式 在前面我们已经搞定了怎样获取页面的内容&#xff0c;不过还差一步&#xff0c;这么多杂乱的代码夹杂文字我们怎样 把它提取出来整理呢&#xff1f;下面就开始介绍一个十分强大的工具&#xff0c;正则表达式&#xff01; 正则表达式是对字符串操作的一种…

力扣Lc28---- 557. 反转字符串中的单词 III(java版)-2024年4月06日

1.题目描述 2.知识点 1)用StringBuilder的方法 实现可变字符串结果 最后返回的时候用.toString的方法 2)在Java中使用StringBuilder的toString()方法时&#xff0c;它会返回StringBuilder对象当前包含的所有字符序列的字符串表示。 在我们的例子中&#xff0c;sb是一个Stri…

Django之五种中间件定义类型—process_request、process_view、process_response.......

目录 1. 前言 2. 基础中间件 3. 如何自定义中间件 4. 五种自定义中间件类型 4.1 process_request 4.2 process_view 4.3 process_response 4.4 process_exception 4.5 process_template_response 5. 最后 1. 前言 哈喽&#xff0c;大家好&#xff0c;我是小K,今天咋们…

90天玩转Python-02-基础知识篇:初识Python与PyCharm

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

ubuntu20.04.6将虚拟机用户目录映射为磁盘Z

文章目录 linux虚拟机设置为NAT模式安装sshd服务映射目录到windows磁盘安装samba套件修改配置文件smb.conf重启smbd并设置用户名和密码 windows映射遇到的问题1、设置好之后映射不成功2、smbd下载失败3、smbd密码配置问题4、当有改动时候&#xff0c;最好重启一下smbd服务 linu…

图解大型网站多级缓存的分层架构

前言 缓存技术存在于应用场景的方方面面。从浏览器请求&#xff0c;到反向代理服务器&#xff0c;从进程内缓存到分布式缓存&#xff0c;其中缓存策略算法也是层出不穷。 假设一个网站&#xff0c;需要提高性能&#xff0c;缓存可以放在浏览器&#xff0c;可以放在反向代理服…

4月6号排序算法(2)

堆排序 讲堆排序之前我们需要了解几个定义 什么叫做最大堆&#xff0c;父亲节点&#xff0c;以及孩子节点 将根节点最大的堆叫做最大堆或大根堆&#xff0c;根节点最小的堆叫做最小堆或小根堆。 每个节点都是它的子树的根节点的父亲 。 反过来每个节点都是它父亲的孩子 。 …

post请求搜索功能爬虫

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency>…

「 典型安全漏洞系列 」11.身份验证漏洞详解

身份验证是验证用户或客户端身份的过程。网站可能会暴露给任何连接到互联网的人。这使得健壮的身份验证机制成为有效的网络安全不可或缺的一部分。 1. 什么是身份验证 身份验证即认证&#xff0c;是验证给定用户或客户端身份的过程。身份验证漏洞使攻击者能够访问敏感数据和功…

网络安全之命令注入

漏洞原理&#xff1a; 应用系统设计需要给用户提供指定的远程命令操作的接口&#xff0c;比如&#xff1a;路由器&#xff0c;防火墙&#xff0c;入侵检测等设备的web管理界面。一般会给用户提供一个ping操作的web界面 用户从web界面输入目标IP&#xff0c;提交后台会对改IP地…

C语言 练习题

目录 1.统计二进制中1的个数 方法1 方法2 方法3 2.求两个数二进制中不同位的个数 方法1 方法2 3.打印整数二进制的奇数位和偶数位 4.用“ * ”组成的X形图案 5.根据年份和月份判断天数 6.结语 1.统计二进制中1的个数 【题目内容】 写一个函数返回参数二进制中 1 的个…

MATLAB实现数值求解高阶常微分方程组

一、高阶常微分方程组 高阶常微分方程是指包含多个高阶常微分方程的系统。这些方程通常涉及多个未知函数及其高阶导数。解决高阶常微分方程组通常比解决单个高阶常微分方程更为复杂&#xff0c;因为需要同时考虑多个方程和多个未知函数之间的关系。 一般来说&#xff0c;解决…