如何在程序运行的时候动态给程序分配内存?

文章目录

  • 1 动态内存分配的意义
    • 1.1 C语言中如何动态申请内存空间
    • 1.2 malloc和free的用法
    • 1.3 calloc与realloc
      • 1.31 calloc和realloc的代码案例分析
  • 2 总结

1 动态内存分配的意义

在C语言中,一切操作都是基于内存的。变量和数组名都是内存别名。但是它们的内存分配却是在编译期间由编译器决定的。定义数组的长度的时候,必须指定长度,这是在编译期间就要确定的。

但是,需求总是有的。比如当我们无法在编译期间确定到底需要多大的内存块,此时就无法定义数组的大小(或者定义的数组大小不够)。此时就需要在运行的时候根据实际的情况(比如根据输入的数据的大小),来动态的申请内存空间,然后让数组(指针)指向这块新申请的内存。

这就是动态内存分配的意义。

1.1 C语言中如何动态申请内存空间

  • malloc和free用于动态申请内存和释放内存

它们的操作对象是堆空间内存(内存池)如下图:

注意:malloc和free必须是成对出现的,这样可以避免内存泄露。关于内存泄露,后面还有文章进行学习。

1.2 malloc和free的用法

malloc和free的函数定义如下:

  • malloc所分配的是一块连续的内存,参数size是所分配的内存字节数。
  • malloc的返回值是void* ,具体使用的时候需要做强制类型转换
  • free用于将申请的动态内存归还给系统

关于malloc和free,有以下几点需要注意:

  1. malloc和free是库函数,不是系统调用
  2. malloc实际分配的内存,可能比请求的多。这是因为CPU访问内存是按照一种内存对齐的方式来访问的。所以一般申请的内存都是对齐内存的整数倍
  3. 当请求的动态内存无法满足的时候,malloc返回NULL
  4. 当free的参数为NULL的时候,函数直接返回。
  5. malloc申请的动态内存中的数据是随机值,不会被初始化为0

至于malloc和free的用法,在前面的文章已经学会使用了,这里不再给出例子,直接看前面的文章吧:二维数组与二维指针

以及在后面的文章中,会给出一个内存泄露检测模块,来巩固malloc与free的使用。自行去后面的文章查看。

1.3 calloc与realloc

函数原型为;

  • calloc的参数:num个类型长度为size的内存空间大小。也就是申请的内存的类型信息(大小和类型)
  • calloc会将申请的内存空间初始化为0
  • realloc用于修改原先已经分配的内存块大小
    1. 当realloc的第一个参数pointer为NULL时,realloc相当于malloc
    2. realloc一般是重新找一块新的内存块进行分配,而不是在原有的内存的结尾增加。

1.31 calloc和realloc的代码案例分析

  • 代码:38-2.c
#include <stdio.h>
#include <malloc.h>#define SIZE 5
int main() {int  i = 0;int* pI = (int*)malloc(SIZE * sizeof(int));short* pS = (short*)calloc(SIZE, sizeof(short));for (i = 0; i < SIZE; i++) {printf("pI[%d] = %d, pS[%d] = %d\n", i, pI[i], i, pS[i]);}printf("Before: pI = %p\n", pI);pI = (int*)realloc(pI, 2 * SIZE * sizeof(int));printf("After: pI = %p\n", pI);for (i = 0; i < 10; i++) {printf("pI[%d] = %d\n", i, pI[i]);}printf("\n");pS = (short*)realloc(pS, 2 * SIZE * sizeof(short));for (i = 0; i < 10; i++) {printf("pS[%d] = %d\n", i, pS[i]);}free(pI);free(pS);return 0;
}
  • 上述代码运行结果:

Linux下gcc 4.4.5编译:

Windows下 VS 2017运行如下:

  • 分析:
  1. 首先代码很很简单。无非就是使用了malloc,calloc和realloc三个函数。其中我们可以看到,在Linux下的gcc4.4.5编译器将malloc申请的内存的内容也都是0,并不是随机值。但是这只是巧合或者gcc编译器优化了而已。在windows下的vs2017编译器就很明显,malloc申请的内存的内容都是随机值
  2. 根据两个结果,可知道,使用realloc后,内存的地址变了,也就是说realloc是重新选择一块内存进行分配,并不是在原有的内存空间结尾增加
  3. 也可以看到不管是在linux下还是在windows下,calloc申请的内存的内容都被初始化为0了
  4. 从windows下的编译运行结果来看,使用realloc对之前使用calloc申请的内存重新分配内存后,原有的内容不变,但是新添加的内容并不是0,而是随机值,这个也要注意。

所以最终总结为:只有calloc胡为分配的内存的内容初始化为0,malloc和realloc都是随机值。

2 总结

  • 动态内存分配使得程序在需要的时候有机会获得更大的内存
  • malloc单纯的从系统中申请固定字节大小的内存。内存中的内容是随机值
  • calloc 申请的内存的内容被初始化为0
  • realloc用于重置内存的大小。但是是重新在堆空间中选一块内存而不是在原有的内存后面增加。并且,重置的内存中,原有的内容不变,但是如果内存变大,多余的部分的内存的内容是随机值。
  • 注意上述三者函数的参数与返回类型
  • 学会使用上述三者函数

【C语言进阶深度学习记录】三十三 C语言中动态内存分配相关推荐

  1. 【C语言进阶深度学习记录】十三 C语言中 ++和--操作符

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 文章目录 1 ...

  2. 【C语言进阶深度学习记录】五 C语言中变量的属性

    上一篇文章学习了C语言中的类型转换,点击链接查看:[C语言进阶深度学习记录]四 C语言中的类型转换. 文章目录 1 C语言的变量属性 1.1 auto关键字 1.2 register关键字 1.3 s ...

  3. 【C语言进阶深度学习记录】七 C语言中的循环语句

    文章目录 1 循环语句分析 1.1 do...while循环 1.2 while循环 1.3 for循环 1.4 三种循环语句使用对比 2 break和continue的区别 3 总结 1 循环语句分 ...

  4. 【C语言进阶深度学习记录】四 C语言中的类型转换

    今天学习C语言中的类型转换,包括隐式类型转换和显示类型转换 文章目录 1 C语言中的数据类型转换 1.1 强制类型转换 1.11 强制类型转换代码分析 1.2 隐式类型转换 1.21 隐式类型转换代码 ...

  5. 【C语言进阶深度学习记录】六 C语言中的分支语句

    文章目录 1 if 语句的分析 1.1 if 语句中零值比较的注意点 2 switch 语句的分析 3 if 与switch语句使用代码案例分析 4 if语句与switch语句的互换 5 总结 1 i ...

  6. 【C语言进阶深度学习记录】三十五 程序中的堆、栈以及静态存储区(数据区)

    学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 在我之前学习底层的知识的时候,也写过相关的内容.可以对比的学习:[软 ...

  7. 【C语言进阶深度学习记录】三十八 C/C++语言中的函数声明与函数定义

    文章目录 1 函数的声明和定义 1.1 代码分析 2 总结 1 函数的声明和定义 声明的意义在于告诉编译器程序单元的存在.只是告诉编译器它存在但是不在声明这里定义,有可能在当前文件中的其他地方或者其他 ...

  8. 【C语言进阶深度学习记录】二十六 C语言中的字符串与字符数组的详细分析

    之前有一篇文章是学习了字符和字符串的,可以与之结合学习:[C语言进阶深度学习记录]十二 C语言中的:字符和字符串 文章目录 1 字符串的概念 1.1 字符串与字符数组 1.2 字符数组与字符串代码分析 ...

  9. 【C语言进阶深度学习记录】十九 #pragma使用与分析

    文章目录 1 #pragma 概念简介 1.1 #pragma message 的用法 1.2 #pragma once 的用法 1.3 #pragma pack 的用法 1.31 struct占用的 ...

  10. 【C语言进阶深度学习记录】十六 静态库与动态库的创建与使用

    上一篇文章学习了编译的过程,点击链接查看:[C语言进阶深度学习记录]十五 编译过程简介,每一个C源文件编译后将会生成目标文件,那么这些目标文件,还需要链接起来,生成可执行文件. 文章目录 1 链接的意 ...

最新文章

  1. 搭建Git服务器教程转载
  2. Mac OS X 10.9 装gdb
  3. java 堆大小的最大值_优化Java堆大小的5个技巧
  4. 03_TortoiseGit冲突和补丁演示,补丁冲突
  5. TensorFlow:实战Google深度学习框架(四)MNIST数据集识别问题
  6. 【渝粤题库】陕西师范大学200711 面向对象方法与C++ 作业
  7. C---编写程序:实现一个随堂测试,能进行加减乘除运算。要求如下:(1)随机产生两个1~10的正整数,在屏幕上输出题目,如:5+3=?(2)学生输入答案,程序检查学生输入答案是否正确,若正确,
  8. Android使用Aspectj(AOP)
  9. 摩拜服务器维护,摩拜的后台是云服务器
  10. 【转】flash不建议设置wmode及wmode解释
  11. 麻省理工线性代数第二讲
  12. C++类的声明和类的实现分开写(.hpp和.cpp)
  13. Java的指针碰撞简介
  14. 2022-2028全球智能门锁系统行业调研及趋势分析报告
  15. PYTHON 用几何布朗运动模型和蒙特卡罗MONTE CARLO随机过程模拟股票价格可视化分析耐克NKE股价时间序列数据...
  16. 苹果开发---window配置苹果虚拟机 和安装xcode
  17. selenium通过cookie跳过登录验证码实现登录
  18. 语音识别提取视频文案
  19. Git 常用命令大全-转载
  20. 爬虫-域名抢注(whois.ai)

热门文章

  1. mybatis学习(37):动态sql-trim
  2. spring mvc学习(21):testparam请求参数和请求头表达式
  3. 68 cookie在登录中的作用
  4. 65 modol1用户登录
  5. 实例27:python
  6. xxljob 配置具体定时任务_记一次xxl-job定时任务没有触发的问题
  7. 我对CSS vertical-align的一些理解与认识(二)
  8. 特征工程之数据预处理(下)
  9. 有限状态自动机java实现_用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机...
  10. 算法之排序算法-选择排序与优化