c语言 什么时候需要动态分配内存?

2023-11-04

我讲解一下c语言中动态分配内存的函数,可能有些初学c语言的人不免要问了:我们为什么要通过函数来实现动态分配内存呢?系统难道不是会自动分配内存吗??

既然有人会问这样的问题,那么我在这里好好的讲解一下吧!

首先让我们熟悉一下计算机的内存吧!在计算机的系统中有四个内存区域:

1)栈:在栈里面储存一些我们定义的局部变量以及形参(形式参数);

2)字符常量区:主要是储存一些字符常量,比如:char *p_str=”cgat”;其中”cgat”就储存在字符常量区里面;

3)全局区:在全局区里储存一些全局变量和静态变量;

4)堆:堆主要是通过动态分配的储存空间,也就是我们接下需要讲的动态分配内存空间。

什么时候我们需要动态分配内存空间呢?举一个例子吧。int *p; 我们定义了一个指向int类型的指针p;p是用来储存一个地址的值的,我们之所以要为p这个变量分配空间是让它有一个明确的指向,打个比方吧!你现在做好了一个指向方向的路标,但是你并没有让这个路标指向一个确切的方位,也就是说现在的这个路标是瞎指向的,这样我们就不能够通过它来明确到底哪里是东,哪里是西,何为北,何为南了。虽然我们在计算机的内存里定义了一个指针变量,但是我们并没有让这个变量指示一个确切int类型变量的地址,所以我们就必须要让它有一个明确的指示方向。这样我们就要通过动态分配内存的方式来认为的规定它的方向!
我们在刚刚接触指针的时候遇到过这样的情况,int *p;p=&a;这种方法不是指针的动态分配内存,这个叫做指针变量的初始化!初始化同样也可以让指针变量有方向可指。
int *p;p=malloc(n*sizeof(类型名称));我们通过malloc()函数为一个指针变量p分配了地址,这样我们从键盘上键入的值就这样存储在p里面了,接下来我们就可以对这个p进行具体的操作了,比如scanf(“%s”,p)等等。当我们对p结束操作的时候还要释放p的内存空间。为什么要释放内存空间呢?在上面我已经讲过动态分配的变量时储存在堆里面,但是这个堆的空间并不是无限大的,也许当我们编一个小的程序的时候可能我们并不能够发现什么,但是对于那些大的程序,如果我们没及时释放堆的空间的时候会放生内存泄露。所谓内存泄露是因为堆的空间被我们动态分配用完了,这样当我们再去使用动态分配堆的空间的时候就没有足够的空间让我们使用了,这样就需要占有原来的空间,也就是会把其他的空间来储存我们键入的值,这样会导致原来储存的数据被破坏掉,导致了内存的泄露了。
同时当我们使用malloc()函数的时候还应该注意当我们释放完空间的时候还要将原先的指针变量赋予一个NULL,也就是赋予一个空指针,留着下次的时候使用它!如果我们不赋予|NULL行不行呢??答案是:不行的!如果我们不赋予一个空指针这样会导致原先的指针变量成为了一个野指针!何谓野指针?野指针就是一个没有明确指向的指针,系统不知道它会指向什么地方,野指针是很危险的,因此当我们每次使用完malloc()函数的时候都必须将指针赋予一个空指针!相对于malloc()函数,calloc()函数就不需要我们赋予NULL了,这是因为在每次调用完calloc()函数的时候系统会自动将原先的指针赋予一个空指针,即归于“0”。calloc()函数的原型是void *calloc(count,sizeof(类型名称));比如:p=(char*)calloc(4,sizeof(char));我们为p分配了指向char型指针的“4”个空间。
除了malloc()与calloc(),还有一个动态分配空间的函数realloc()函数,这个函数比前两个函数分配更多的空间,原型:void *realloc(void *p,size_t size);
该函数有几个作用:
1)    如果有足够的空间来扩充p的内存块,则返回一个指向p的指针;
2)    如果没有足够的空间来扩充p的内存块,则为p从新分配size的空间,并把原来的内容复制给p,指向p的开头,同时释放原来的空间,返回一个指向新内存块的指针;
3)    如果p=NULL,其作用于malloc()相似;

下面举一个程序的例子:

#define LONG 10
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
main()
{
   char *message,buf[LONG];
   gets(buf);
   message=(char*)realloc(NULL,strlen(buf)+1);
   strcpy(message,buf);
   puts(message);
   gets(buf);
   message=(char*)realloc(message,(strlen(message)+strlen(buf)+1));
   strcat(message,buf);
   puts(message);
   return 0;
}


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c语言 什么时候需要动态分配内存? 的相关文章

  • 微信小程序设置允许转发分享onShareAppMessage(Object object)

    在需要分享的页面js文件中写 Page onShareAppMessage const promise new Promise resolve gt setTimeout gt resolve title 自定义转发标题 2000 retu
  • 基于概率论的分类方法:朴素贝叶斯

    需要分类器做出分类决策 可以使分类器给出各个类别的概率估计值 然后选择概率最高的作为其的类别 在这里使用到了概率论中的贝叶斯公式 P A B P A P B A P B 其中P A B 是后验概率 P A 是先验概率 P B A P B 为
  • Python数据分析与展示第三课

    Matplotlib是python优秀的数据可视化第三方库 数据可视化 将数据以特定的图形图像的形式展现出来 Matplotlib由各种可视化的类构成的 使用方式 import matplotlib pyplot as plt as plt
  • 论文收录引用证明常见问题汇总

    学术论文在毕业 评职称 保研 考博 留学等方面均有重要意义 因此往往需要开具检索证明 然而 开具检索证明的前提是论文必须被收录 1 什么是论文收录引用证明 论文收录引用证明是用来证明作者在科研领域中的实力和成就 当用户需要查询其论文在指定数
  • 单链表实现多项式相加

    这个小项目用C语言实现 代码中有我的注释 思路 用链表的每个节点存储表达式的每一项 因此每个链表就是一个表达式 链表节点类型的定义 struct Node DataType elem 项的系数 Variate ch 常量和变量的标志 规定如
  • rand()每次产生的随机数都一样

    写了个程序 每次产生的随机数都是一样的 在调用之前已经初始化了随机数种子 用的是当前时间 可是还是得到一样的数 for int i 0 i lt 100000 i srand unsigned time NULL cout lt
  • shiro入门

    1 概述 Apache Shiro 是一个功能强大且易于使用的 Java 安全 权限 框架 借助 Shiro 您可以快速轻松地保护任何应用程序一一从最小的移动应用程序到最大的 Web 和企业应用程序 作用 Shiro可以帮我们完成 认证 授
  • Vue中获取input输入框值

  • 一个“制作午餐”的故事,帮助你理解并发和并行(上)

    导读 这是一个关于 午餐时间 的小故事 用于阐述 threading asyncio multiprocessing cloud functions 等内容 为了方便阅读并理解文章的内容 全文分上 下两篇 上篇主要讲解并发 下篇重点讲解并行
  • runtime交换方法的正确姿势

    runtime交换方法的正确姿势 说到Objective C大家就会想到黑魔法runtime 不知道runtime是什么的看这里 runtime是开源的 源码在这里 本文主要讲解如何利用runtime正确的交换方法 将会提到两种方式去交换
  • 在Linux的终端中显示BMPString的内容

    在上一篇博文中 介绍了如何在 Windows 的控制台界面下输出 BMPString 的内容 但是那里的方法在 Linux 下不适用 如果将那里的示例代码放到 Linux 下执行 输出的结果为乱码 产生乱码的原因在于 wchar t 类型的
  • 数据挖掘——第一章:概述

    文章目录 1 数据分析与数据挖掘 1 1 数据分析 1 2 数据挖掘 1 3 知识发现 KDD 的过程 1 4 数据分析与数据挖掘的区别 1 5 数据分析与数据挖掘的联系 2 分析与挖掘的数据类型 2 1 数据库数据 2 2 数据仓库数据
  • 思科网络配置简单学习

    一 VLAN 什么是VLAN 虚拟局域网 为什么要引入VLAN 1 交换机分割了冲突域 但是不能分割广播域 2 交换机端口数量增多 网络中广播增多 降低了网络的效率 3 目的为了分割广播域 VLAN的优势 广播控制 提高安全性 提高带宽利用
  • UDP \TCP详详详详解,你想要的全都有(呕心沥血)

    前言 因特网为应用层提供了两种截然不同的可用运输层协议 一个是UDP 用户数据报协议 一个是TCP 传输控制协议 这两种协议无论是在开发过程中 还是面试问答中 都相当重要 先了解两个定义 多路分解 将运输层报文段中的数据交付到正确的套接字
  • 2023 年 30 种顶级自动化测试工具

    当您想运行测试自动化时 天空是极限 甚至超越极限 技术发展如此之快 与 10 年前相比 您可以减少时间并保持更高的工作效率 如果 Selenium 是您首选的自动化测试工具 您就不必忍受 Selenium 给您带来的限制 相反 您可以从各种
  • Python基础知识(一):变量与赋值、运算符、数据类型及位运算

    学习目标 了解python的基本概念 变量类型 运算符 及数据类型 了解python的位运算 原码 反码和补码 注释 在 Python 中 表示注释 作用于整行 或者 表示区间注释 在三引号之间的所有内容被注释 在Pycharm或者Jupy
  • matlab 安装mingw64

    1 下载mingw64 MinGW w64 for 32 and 64 bit Windows download SourceForge net 解压到没有空格的路径 好像必须在c盘 否则可以出现 错误使用 configuremingw 无
  • List元素为类对象,按照类对象属性去重的解决办法

    很多小伙伴在开发中会遇到一个场景 就是List集合中存储的是类对象 我们想要根据类对象属性去重 这种场景该如何做呢 解决办法 大家都知道对象的equals默认是按照对象的应用地址去进行比较的 所以想要对象去重 关键就在于重写equals方法
  • 三极管驱动继电器详解

    http www 21ic com jichuzhishi analog basic 2015 08 24 638790 html

随机推荐

  • 基于STM32的多功能心电信号监测系统设计

    1 系统总体方案设计 系统由STM32F103微处理器模块 ADS1292R心电采集模块 LMT70体表温度传感器模块 ESP8266无线WiFi模块 MMA955L加速度计模块 系统电源 PC服务端等组成 STM32F103作为主控制器实
  • 2.4 Verilog HDL语句

    语句 1 赋值语句 结构说明语句 阻塞与非阻塞 1 1 赋值语句 1 1 1 连续赋值语句assign 1 1 2 过程赋值语局 和 lt 1 2 结构说明语句 1 2 1 结构说明语句always 1 2 2 结构说明语句initial
  • 【机器学习】噪声数据的理解

    文章目录 一 噪声数据 1 1 分箱 1 2 回归 1 3 聚类 1 4 其他 二 数据清理作为一个过程 2 1 偏差检测 2 1 1 使用 元数据 关于数据的数据 2 1 2 编码格式 存在使用不一致 数据表示不一致 2 1 3 字段过载
  • C语言编程中的8位、16位、32位整数的分解与合并

    在单片机的编程中对于8位 16位 32位整数的分解与合并用的比较多 今天做了简要学习 后面还需要加以总结 练习在VC 6 0编程环境中进行 源程序 include
  • pikachu靶场--SQL inject--数字型(post)/字符型(get)/搜索型/xx型注入【4.1】~【4.4】

    目录 一 概述 二 数字型注入 post 三 字符型注入 get 四 搜索型注入 以搜索k为例 五 xx型注入 一 概述 在owasp发布的top10排行榜里 注入漏洞一直是危害排名第一的漏洞 其中注入漏洞里面首当其冲的就是数据库注入漏洞
  • python 变量赋值 修改之后 原值改变

    python 是一种动态语言 因此变量的类型和值 在运行时均可改变 当我们将一个变量赋值给另一个变量时 实际上是将变量的引用地址传递给新的变量 这意 味着新旧变量将指向同一个位置 因此 在更改其中一个变量的值时 另一个变量的值也会被更改 i
  • pig对应sql的基本命令

    1 从文件导入数据 1 Mysql Mysql需要先创建表 CREATE TABLE TMP TABLE USER VARCHAR 32 AGEINT IS MALE BOOLEAN CREATE TABLE TMP TABLE 2 AGE
  • 【Java】final关键字的细节注意(八)

    这节内容较简单 而且内容较少 课程源自韩顺平老师的Java课程 final关键字的使用 final的需要注意的细节
  • Android UI 基础-坐标系、角度(弧度)、颜色

    目录 1 坐标系 1 1 屏幕坐标系和数学坐标系的区别 1 2 View的坐标系 1 3 MotionEvent中 get 和 getRaw 的区别 1 4 核心要点 2 角度与弧度 2 1 角度与弧度的定义 2 2 角度和弧度的换算关系
  • linux 进入目录命令

    直接进入计算机目录下 常用指令 cd home 进入 home 目录 cd 返回上一级目录 cd 返回上两级目录 cd 进入个人的主目录 cd user1 进入个人的主目录 cd 返回上次所在的目录 ls 显示文件或目录 l 列出文件详细信
  • 移动端常见meta设置

    1 设置viewport 这句话设置viewport的宽为设备的宽 禁止用户进行缩放 此外 常见参数设置 a width 宽度 数值 device width 默认为980 b height 高度 数值 device height c in
  • 手写一个根据目录自动生成的路由

    文章目录 一 起因 二 思索 三 测试效果 四 项目代码 一 起因 最近研究了一下阿里dva的quickstart 其中路由配置是手动添加 如下 先将要显示的页面导入router js 然后配置 其中path products 是配置的路由
  • 在pycharm中配置变量

    实验目的 python run classifier py task name MRPC do train true do eval true data dir GLUE DIR MRPC vocab file BERT BASE DIR
  • es 索引类型与分词器调整与迁移

    索引最好起别名 方便索引调整 1 创建新索引 PUT index v2 settings number of shards 5 number of replicas 1 mappings doc dynamic strict propert
  • Python爬虫中文乱码问题

    我们在爬虫输出内容时 常常会遇到中文乱码情况 以如下网址为例 https chengdu chashebao com yanglao 19077 html 在输出内容时 出现如下图的情况 解决爬虫中文乱码的步骤 网址编码为gbk 查看网页源
  • shell与shell脚本(一)基本概念与常用的shell命令

    前言 像linux windows等的操作系统 都很大程度上地便利了我们操作计算机的能力 计算机之所以能高效处理用户指令 是因为CPU 更细致地讲 是因为CPU中的内核 也就是我们所说的运算器 控制器和寄存器 当然 我们在使用计算机是 不可
  • 四、同步方法与异步方法及回调函数

    解释一下同步方法与异步方法以及回调函数的关系 若不想很深入的了解这方面内容 可以记住以下结论 对于同时有同步方法和对应异步方法的函数 我们常用异步方法 用独立线程去处理该函数 提高用户的体验 异步方法由于我们需要等待某种事件的发生 例如当前
  • mysql插入数据时,在数据库和表的编码都是utf-8的情况下,还是出现乱码

    Mysql插入数据时 在数据库和表的编码都是utf 8的情况下还是会出现乱码 解决方法 首先先确定自己的数据库的编码是否是utf 8 查看数据库字符集 将sct换为自己的数据库的名字 SHOW CREATE DATABASE sct 会看到
  • vue 项目 基于axios 对常用5种(POST、GET、PUT、DELETE、PATCH)请求进行封装

    一 安装axios 使用 npm npm install axios save 使用 cnpm cnpm install axios save 使用 yarn yarn add axios save 建议使用cnpm 二 src目录下新建l
  • c语言 什么时候需要动态分配内存?

    我讲解一下c语言中动态分配内存的函数 可能有些初学c语言的人不免要问了 我们为什么要通过函数来实现动态分配内存呢 系统难道不是会自动分配内存吗 既然有人会问这样的问题 那么我在这里好好的讲解一下吧 首先让我们熟悉一下计算机的内存吧 在计算机