传统数组的缺点:

1,数组的长度必须实现预定,且是常整数,不能是变量,

例如:

int a[5];   //正确

int  len=5;  int a[len];   //error

2,传统形式定义的数组,该数组内存程序员无法手动释放,在一个函数运行期间,系统为该函数中的数组所分配的空间会一直存在,直到该函数运行完毕,数组的空间才会被系统释放。

3,数组的长度不能在函数程序运行的过程中动态的扩充或缩小(长度定义之后就不能变化)

4,A函数定义的数组,在A函数运行期间可以被其他函数使用,但是A函数运行完毕之后,A函数中的数组将无法在被其他函数使用

传统型定义的数组无法跨函数使用(在一个函数内部定义的数组这个函数运行结束之后就释放了)

void g(int * pArr, int length) {pArr[2] = 88;   //通过指针改变数组的值
}void function(void) {int a[5] = { 1,2,3,4,5 };g(a, 5);  //调用g(a,5)函数printf("%d\n", a[2]);
}int main() {char ch = 'A';int i = 99;double x = 66.6;char *p = &ch;int *q = &i;double *r = &x;
/*一个指针占用四个字节具体参考上一篇文章:https://blog.csdn.net/ywl470812087/article/details/103380837*/
//  printf("%d  %d  %d", sizeof(p), sizeof(q), sizeof(r));  //4   4   4function();   //调研function()while (true){}}

为什么需要动态内存分配?

我讲解一下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;
}

当你不确定内存空间大小的时候。。有2种办法。
1。预先定义一个足够大的空间。(这个比较浪费资源。而且随着程序的使用推广。预先定义的空间也不一定能完全满足条件)
2。动态的分配内存。可以做到准确分配空间大小。不浪费资源,而且也不会发生程序不断使用预先分配内存不足。
备注:动态分配的内存空间系统不负责自动回收,需要写代码手动释放。

为什么需要动态内存分配?相关推荐

  1. 释放变量所指向的内存_C++动态内存分配(学习笔记:第6章 15)

    动态内存分配[1] 动态申请内存操作符 new new 类型名T(初始化参数列表) 功能: 在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值. 结果值: 成功:T类型的指针,指向 ...

  2. 动态内存分配与柔性数组

    什么时动态内存分配 一般我们写程序都是在栈区分配空间,如果我们想根据需求想随时存放随时释放数据,堆区可以实现根据需求想系统申请所需大小的空间. 建立内存的动态分配 内存的动态分配是通过系统提供的函数来 ...

  3. C++中的动态内存分配

    1.Cpp中的内存分配 了解动态内存在C++中是如何工作的是成为一名合格的C++程序员必不可少的.C++程序中的内存分为两个部分: 栈:在函数内部声明的所有变量都将占用栈内存. 堆:这是程序中未使用的 ...

  4. 【 C 】动态内存分配实用案例(二)之复制字符串

    用动态分配内存制作一个字符串的一份拷贝.注意:调用程序应该负责检查这块内存是否分配成功,这样做允许程序以任何它所希望的方式对错误作出反应. #nclude <stdlib.h> #incl ...

  5. 【 C 】动态内存分配实用案例(一)之读取、排序和打印一列整形值

    什么时候用动态内存分配呢?下面这个案例给出了一个比较实用且精彩地使用动态内存的场合,并且教你如何合理地使用动态内存分配? 动态内存分配一个常见的用途就是为那些长度在运行时才知的数组分配内存空间. 下面 ...

  6. 【 C 】动态内存分配案例分析

    声明一个指向char类型的指针,可以在声明的时候就对其进行初始化,这样是合理的. 例如: E1: #include <stdio.h> #include <stdlib.h> ...

  7. 【C 语言】内存管理 ( 动态内存分配 | 栈 | 堆 | 静态存储区 | 内存布局 | 野指针 )

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  8. 从更底层研究C\C++动态内存分配

    2019独角兽企业重金招聘Python工程师标准>>> 以前在学C++ 的时候,一直不懂:动态内存分配的本质,或者更加深入到底层的意义.虽然说,动态内存分配就是,随机在内存中分配一个 ...

  9. 静态、动态内存分配比较

    首先,在使用动态分配内存技术前,必须明白自己在做什么,这样做与其它的方法有什么不同,特别是会产生哪些负面影响,天下没有免费的午餐.动态分配内存与静态分配内存的区别: 1) 静态内存分配是在编译时完成的 ...

  10. 动态内存分配到底为谁分配内存空间【浅谈动态内存的一个实例】

    为了动态的管理宝贵的内存,许多程序中要使用到动态内存分配.一般情况下,在c语言中,使用malloc()函数来分配指定大小的内存空间,用free()函数来释放这块内存空间.但是,往往初学者在编写这类程序 ...

最新文章

  1. c4d跟踪特效合成视频教程 Master Motion Tracking with Cinema 4D
  2. py2exe——.py文件转换成exe
  3. wxWidgets:wxHyperlinkCtrl类用法
  4. 某聊天工具消息记录数据库文件解密逆向分析
  5. Spring Boot-springbootHelloword(一)
  6. OpneCV之图像的平移、翻转、旋转、缩放、裁剪(笔记04)
  7. html中右边框出不来,html,为什么右边框会被挡住?
  8. saltstack event 实践
  9. 股票市值高好还是低好呢?
  10. 挪车让路,没有留下电话怎么办?
  11. 附pdf下载 | 《机器学习数学基础》电子书
  12. wifi协议-802
  13. 白嫖UltraEdit、UltraCompare等等类似工具(2021.2.16更新)
  14. 2021厦大计算机考研炸了,厦门大学2021年硕士研究生复试名单
  15. js怎么实现ftp上传文件到服务器,js ftp上传文件到服务器上
  16. cdn加速的原理及步骤
  17. Cannot find name ‘console‘. Do you need to change your target library?ging the ‘lib‘ compiler option
  18. MATLAB学习【第五部分】--第一节:矩阵的输入//冒号表达式矩阵---linspace函数生成向量---一般矩阵输入
  19. 别让所谓的“富人思维”毁了你
  20. 牛客网sql练习笔记(二)

热门文章

  1. python如何下载库_python中如何下载库
  2. R之Excel文件读取与程序包的安装调用
  3. python的gui编程pyqt5_Python-GUI编程-PyQt5
  4. python基础课程6(看代码看注释)--pandas
  5. java不大于6位_末尾带4的完全平方数的数量并且打印输出_Java计算一个数加上100是完全平方数,加上168还是完全平方数...
  6. Python Pytest中fixture之yield唤醒teardown和终结函数addfinalizer
  7. poj 2406 还是KMP的简单应用
  8. pdf.js 文字丢失问题 .cmaps
  9. [CF706D]Vasiliy's Multiset(异或字典树)
  10. 在ubuntu上搭建开发环境9---Ubuntu删除ibus出现的问题及解决