realloc的使用误区
C语言 realloc() 函数位于 stdlib.h 头文件中,原型为:
void *realloc(void *ptr, size_t size);
realloc() 会将 ptr 所指向的内存块的大小修改为 size,并将新的内存指针返回。
设之前内存块的大小为 n,如果 size < n,那么截取的内容不会发生变化,如果 size > n,那么新分配的内存不会被初始化。
如果 ptr = NULL,那么相当于调用 malloc(size);如果 size = 0,那么相当于调用 free(ptr)。
如果 ptr 不为 NULL,那么他肯定是由之前的内存分配函数返回的,例如 malloc()、calloc()或realloc()。
如果 ptr 所指的内存块被移动,那么会调用 free(ptr)。
一个简单的 realloc() 却赋予了好几个功能,这并不是良好的函数设计。估计也是为了兼容性,才容忍这个函数一直在C库中。虽然在编码中,realloc() 会提供一定的方便,但是也很容易引发Bug。下面是两个常见bug用法:
第1种行为引发的Bug
- void *ptr = realloc(ptr, new_size);
- if (!ptr) {
- // 错误处理
- }
这里就引出了一个内存泄露的问题,当realloc() 分配失败的时候,会返回NULL。但是参数中的 ptr 的内存是没有被释放的。如果直接将realloc()的返回值赋给ptr。那么当申请内存失败时,就会造成ptr原来指向的内存丢失,造成内存游离和泄露。
正确的处理应该是这样:
- void *new_ptr = realloc(ptr, new_size);
- if (!new_ptr) {
- // 错误处理。
- }
- ptr = new_ptr
第2种行为引发的Bug
实际上,malloc(0)是合法的语句,会返还一个合法的指针,且该指针可以通过free去释放。这就造成了很多人对realloc()的错误理解,认为当size为0时,实际上realloc()也会返回一个合法的指针,后面依然需要使用free去释放该内存。
- void *new_ptr = realloc(old_ptr, new_size);
- //其它代码
- free(new_ptr);
由于错误的认识,不去检验new_size是否为0,还是按照new_size不为0的逻辑处理,最后并free(new_ptr)。这里就引入了double free的问题,造成程序崩溃。
所以,realloc() 这个设计并不怎么优良的函数陷阱还是不少的,一不小心就踩雷了,上面只是两个简单的小例子,大家在实际使用的时候还应该注意一些其他小问题。
realloc的使用误区的更多相关文章
- 常见CSS与HTML使用误区
误区一.多div症 <div class="nav"> <ul> <li><a href="/home/"> ...
- C# - 值类型、引用类型&走出误区,容易错误的说法
1. 值类型与引用类型小总结 1)对于引用类型的表达式(如一个变量),它的值是一个引用,而非对象. 2)引用就像URL,是允许你访问真实信息的一小片数据. 3)对于值类型的表达式,它的值是实际的数据. ...
- 关于SQL Server镜像的一个小误区
昨天晚上突然接到客户的电话, 说在配置了镜像的生产环境数据库下修改 “已提交读快照” 选项的时候报错, 需要先取消镜像然后再重新搭建.悲催的是这是个近TB的数据库,问我有没有什么快速的方法.于是我就问 ...
- C 语言中 malloc、calloc、realloc 和free 函数的使用方法
C标准函数库中,常见的堆上内存管理函数有malloc(), calloc(), recalloc(), free(). 之所以使用堆,是因为栈只能用来保存临时变量.局部变量和函数参数.在函数返回时,自 ...
- 内存动态分配之realloc(),malloc(),calloc()与new运算符
1,malloc与free是C/C++的标准库函数,new/delete是C++的运算符,是C++面向对象的特征,它们都可用于申请动态内存和释放内存.2,对于非内部数据类型的对象而言,光用maloc/ ...
- SQL Server CheckPoint的几个误区
有关CheckPoint的概念对大多数SQL Server开发或DBA人员都不陌生.但是包括我自己在内,大家对于CheckPoint都或多或少存在某些误区,最近和高文佳同学(感谢高同学的探讨) ...
- Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解
C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...
- Fouandation(NSString ,NSArray,NSDictionary,NSSet) 中常见的理解错误区
Fouandation 中常见的理解错误区 1.NSString //快速创建(实例和类方法) 存放的地址是 常量区 NSString * string1 = [NSString alloc]init ...
- css2 [lang|=en] 误区
[lang|=en] w3c说明:css2选择器,选择以en开头的的lang属性. w3c的这个解释是有误区的,en开头,但是en后面必须要有-,也就是说是选择的是en-开头
随机推荐
- caffe的python接口学习(5):生成deploy文件
如果要把训练好的模型拿来测试新的图片,那必须得要一个deploy.prototxt文件,这个文件实际上和test.prototxt文件差不多,只是头尾不相同而也.deploy文件没有第一层数据输入层, ...
- 开源任务管理平台TaskManager介绍
很早之前准备写Quartz系列文章,现在终于能够实现了.从本篇开始将带你实现一款自己的任务管理平台.在工作中你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一 ...
- Prototype原型(创建型模式)
依赖关系的倒置:抽象不应该依赖于实现的细节,实现细节应该依赖于抽象. 原型模式的定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.prototype模式允许一个对象再创建另外一个可 ...
- 基于Bootstrap仿淘宝分页控件实现
.header { cursor: pointer } p { margin: 3px 6px } th { background: lightblue; width: 20% } table { t ...
- 【原创】O2O,你真的知道怎么玩吗?
自从2011年8月份,O2O的概念被Alex Rampell提出,并且在当年的11月份被引入中国以来,O2O这一概念就好像给久无新意的中国互联网行业,打了一针兴奋剂.O2O这个词也如麦当劳,星巴克这些 ...
- 备份Mysql数据库BAT脚本
@echo off set "Ymd=%date:~,4%%date:~5,2%%date:~8,2%"c:cd C:\MySQL\bin\mysqldump -h 172.25. ...
- Linux ubuntu安装
http://www.ubuntu.org.cn/download/alternative-downloads 下载地址: http://releases.ubuntu.com/ 国内镜像: http ...
- JavaScript的理解记录(5)
---接上篇: 三.DOM解析: 1.Document Object Model(DOM):是表示和操作HTML和XML文档内容的基础API;其中几个重要的类有:Document和Element,Te ...
- JavaMeloay配置用于系统监控
JavaMelody JavaMelody能够监控Java或Java EE应用程序服务器的运行状况,并以图标的方式显示:java内存.CPU使用情况.用户Session数量.JDBC连接数.http请 ...
- Function构造函数
使用Function构造函数, 也能够创建函数, 和使用关键字function定义函数有几点区别: 使用function关键字这样定义函数: var f = function(x,y) {return ...