C和指针--动态内存分配
1.为什么需要使用动态内存分配
数组的元素存储于内存中连续的位置上,当一个数组被声明时,它所需要的内存在编译时就被分配。当你声明数组时,必须用一个编译时常量指定数组的长度。但是,数组的长度常常在运行时才知道,这是由于它所需的内存空间取决于输入数据。为了避免空间的浪费和超出范围的处理,需要使用动态内存分配。
2.常见的动态内存错误
- 动态内存分配最常见的错误就是忘记检查所请求的内存是否成功分配。被访问的内存可能保存了其他变量的值,对它进行修改将破坏那个变量,修改那个变量将破坏你存储在那里的值,这种类型的bug非常难以发现。
- 动态内存分配的第二大错误来源是操作内存时超出了分配内存的边界。在malloc和free的有些实现中,它们以链表的形式维护可用的内存池,对分配的内存之外的区域进行访问可能破坏这个链表,这有可能产生异常,从而终止程序。
当一个使用动态内存分配的程序失败时,人们很容易把问题的责任推给malloc和free函数。但是它们实际上很少是罪魁祸首。事实上,问题几乎总是出现在你自己的程序中,而且常常是由于访问了分配内存以外的区域引起的。
警告:
当你使用free时,可能出现各种不同的错误。传递给free的指针必须是一个从malloc、calloc或realloc函数返回的指针。传递给free函数一个指针,让它释放一块并非动态分配的内存可能导致程序立即或在晚些时候终止。试图释放一块动态分配内存的一部分也有可能引起类似的问题。
释放一块内存的一部分是不允许的。动态分配的内存必须整块一起释放。但是realloc函数可以缩小一块动态分配的内存,有效地释放它尾部的部分内存。
最后,必须小心,不要访问已经被free函数释放了的内存。假定你对一个指向动态分配的内存的指针进行了复制,而且这个指针的几份拷贝散布于程序各处。你无法保证当你使用其中一个指针时它所指向的内存是不是已经被另一个指针释放。另一方面,必须确保程序中所有使用这块内存的地方在这块内存被释放之前停止对它的使用。
3.内存泄漏
当动态分配的内存不再需要使用时,它应该被释放,这样它以后可以被重新分配使用。分配内存但在使用完毕后不释放将引起内存泄漏。在那些所有执行程序共享一个通用内存池的操作系统中,内存泄漏将一点点榨干可用内存,最终使其一无所有。要摆脱这种困境,只有重启系统。
其他操作系统能够记住每个程序当前拥有的内存段,这样当一个程序终止时,所有分配给它但未被释放的内存全部归还给内存池。但即使在之类系统中,内存泄漏仍然是一个严重的问题,因为一个持续分配却一点不释放内存的程序最终将耗尽可用的内存。
C和指针--动态内存分配的更多相关文章
- C++指针和动态内存分配
指针和动态内存分配 数组与指针 数组 数组名是一个指针常量. 数组名传递数据时,传递的是地址. 数组作为函数参数时不指定第一维大小. 对象数组 A a[2] = {A(1,2)}; 执行时先调用有参数 ...
- C和指针 第十一章 动态内存分配
声明数组时,必须指定数组长度,才可以编译,但是如果需要在运行时,指定数组的长度的话,那么就需要动态的分配内存. C函数库stdlib.h提供了两个函数,malloc和free,分别用于执行动态内存分配 ...
- 《C和指针》 读书笔记 -- 第11章 动态内存分配
1.C函数库提供了两个函数,malloc和free,分别用于执行动态内存分配和释放,这些函数维护一个可用内存池. void *malloc(size_t size);//返回指向分配的内存块起始位置的 ...
- C动态内存分配(C与指针实例)
主要初步介绍malloc.free.calloc.realloc的基本.日后会有更详细的内容. malloc.free分别用于动态内存分配和释放. malloc会从内存池里提取一块合适的内存(连续的) ...
- C++学习笔记(十一):void*指针、类型转换和动态内存分配
void*指针 void关键字表示“空类型”的概念.但是,这里的“空类型”不表示“任意类型”,而是表示不存在的意思,也就是说C/C++不允许你写语句void a,不存在类型为void的东西. void ...
- 数据结构基础——指针及动态内存分配(malloc)
一.指针 C语言中的指针是一种数据类型,比如说我们用int *a;就定义了一个指针a,它指向一个int类型的数.但是这个指针是未初始化的,所以,一般的,我们都在创建指针时初始化它,以免出错,在还不吃的 ...
- C和C指针小记(十六)-动态内存分配
动态内存分配 1.1 为什么使用动态内存分配 直接声明数组的方式的缺点: 1) 声明数组必须指定长度限制.无法处理超过声明长度的数组. 2) 如果声明更大的常量来弥补第一个缺点,会造成更多的内存浪费. ...
- c++ 动态数组,指针与动态内存分配
教学内容: 内存的使用 动态内存分配malloc函数 分配内存时使用sizeof运算符 用指针访问内存 以数组的形式访问内存 一.内存的使用 堆(heap) 在程序执行期间分配内存时,内存区域中的这个 ...
- <c和指针>学习笔记5动态内存分配和预处理器
1 动态内存 比如声明数组得时候,我们需要提前预估数组长度,分配大了浪费,少了就更不好操作了.从而引入动态分配,需要的时候再分配. (1)malloc和free void *malloc(size_t ...
随机推荐
- windows 下OPENSSL 生成秘钥和公钥的方法
1. 生成原始 RSA私钥文件 private_key.pem openssl genrsa -out private_key.pem 1024 2. 将原始 RSA私钥转换为 pkcs8格式 ope ...
- [C++]多源最短路径(带权有向图):【Floyd算法(动态规划法)】 VS n*Dijkstra算法(贪心算法)
1 Floyd算法 1.1 解决问题/提出背景 多源最短路径(带权有向图中,求每一对顶点之间的最短路径) 方案一:弗洛伊德(Floyd算法)算法 算法思想:动态规划法 时间复杂度:O(n^3) 形式上 ...
- npm install --save react-native-device-info报错
报错截图如下: 把react-native-device-info删了再添加还是这样,后面使用yarn就成功了. 然后发现会报错,这里估计是Xcode 9的bug,你只要确保以下显示就可以了.没有自己 ...
- Swift加载Xib创建的Controller
Xib显示如下: <注意箭头处即可> 按住Control键,点击Files'owner拖动到View即可. 加载该控制器如下: func registerClick() { let reg ...
- iOS自适应行高方法及问题
最近一周被项目的动态高度虐的很惨,感觉浪费了很多时间,但是值得高兴的是对动态高度的使用掌握了好多方法,并且知道了方法之间的区别和优缺点. 1.最常用的: UITableView+FDTemplateL ...
- iOS面试-堆和栈的区别
堆和栈的区别: 一.堆栈空间分配区别: 1.栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈: 2.堆(操作系统): 一般由程序员分配释放, ...
- docker attach 和 exec 用法区别
attach 用法 $ sudo docker attach 665b4a1e17b6 #by IDor$ sudo docker attach loving_heisenberg #by Name$ ...
- SSH命令工具研究报告
0 什么是SSH Secure Shell(安全外壳协议,简称SSH)是一种加密的网络传输协议,可在不安全的网络中为网络服务提供安全的传输环境.SSH通过在网络中创建安全隧道来实现SSH客户端与服务器 ...
- No manual entry for printf in section 3
在引入标准库头文件的时候,很多时候要先查询一下该函数所属的库,以及基本用法,在linux系统下,可以使用 man 1-9 函数名称 但是 问题来了,No manual entry for printf ...
- django 之(三) --- 认证|权限
用户模块 登陆注册1:Django2.0 [ 1:N ] user/url.py from django.urls import path from user.views0 import UserT ...