来源:http://www.cnblogs.com/ladd/archive/2012/06/30/2571420.html
realloc函数用来为ptr重新分配大小为size的一块内存,看似很简单,在使用过程中却会发生各种错误。 函数形式为:
void * realloc ( void * ptr, size_t new_size );
最近在网上查看了一些资料,在glibc中没有找到具体的实现(有人找到了可以发给我,ladd.cn@gmail.com),查到了一个开源项目自己写的realloc代码,http://code.google.com/p/mallocspethmeniel/source/browse/trunk/realloc.c?r=23,应该和stdlib里面的实现流程一样。
下面是我画出的函数流程图

这个函数的工作流程:
1.对ptr进行判断,如果ptr为NULL,则函数相当于malloc(new_size),试着分配一块大小为new_size的内存,如果成功将地址返回,否则返回NULL。如果ptr不为NULL,则进入2
2.查看ptr是不是在堆中,如果不是的话会跑出异常错误,会发生realloc invalid pointer(具体原因在后面讲)。如果ptr在堆中,则查看new_size大小,如果new_size大小为0,则相当于free(ptr),讲ptr指针释放,返回NULL,如果new_size小于原大小,则ptr中的数据可能会丢失,只有new_size大小的数据会保存(这里很重要),如果size等于原大小,等于啥都没做,如果size大于原大小,则看ptr所在的位置还有没有足够的连续内存空间,如果有的话,分配更多的空间,返回的地址和ptr相同,如果没有的话,在更大的空间内查找,如果找到size大小的空间,将旧的内容拷贝到新的内存中,把旧的内存释放掉,则返回新地址,否则返回NULL。

这里解释一下,为什么ptr要在堆中,学过编译原理的同学应该都知道C语言中的malloc,realloc,calloc()这种用户主动分配的内存放在堆区,而临时变量放在栈区,这是两块不同的区域。堆区的变量由用户通过free释放空间,而栈区的变量在函数退出后就自动释放,所以这两个区域的变量生存时间不同,不能相互间进行内存分配操作。所以要求ptr必须在堆区,即ptr必须是malloc,realloc或者calloc的返回值,要不然可以为NULL,把realloc变为malloc。
所以使用realloc函数应该注意一下几点:
1.ptr必须为NULL,或者为malloc,realloc或者calloc的返回值,否则发生realloc invalid pointer错误
2.new_size如果小于old_size,只有new_size大小的数据会被保存,可能会发生数据丢失,慎重使用。
3.如果new_size大于old_size,可能会分配一块新的内存,这时候ptr指向的内存会被释放,ptr成为野指针,再访问的时候会发生错误。
4.最后不要将返回结果再赋值给ptr,即ptr=realloc(ptr,new_size)是不建议使用的,因为如果内存分配失败,ptr会变为NULL,如果之前没有将ptr所在地址赋给其他值的话,会发生无法访问旧内存空间的情况,所以建议使用temp=realloc(ptr,new_size)。
参考文章:
1.function realloc  http://www.cplusplus.com/reference/clibrary/cstdlib/realloc/
2.realloc.c http://code.google.com/p/mallocspethmeniel/source/browse/trunk/realloc.c?r=23

以上内容为ladd原创,画流程图花了老长时间,如果转载请注明出处:http://www.cnblogs.com/ladd/archive/2012/06/30/2571420.html

realloc 使用详解(分析realloc invalid pointer、指针无效等错误)【转】的更多相关文章

  1. HttpRuntime详解分析

    HttpRuntime详解分析(上) 文章内容 从上章文章都知道,asp.net是运行在HttpRuntime里的,但是从CLR如何进入HttpRuntime的,可能大家都不太清晰.本章节就是通过深入 ...

  2. lspci详解分析

    lspci详解分析 一.PCI简介 PCI是一种外设总线规范.我们先来看一下什么是总线:总线是一种传输信号的路径或信道.典型情况是,总线是连接于一个或多个导体的电气连线,总 线上连接的所有设备可在同一 ...

  3. realloc() 用法详解

    原型:extern void *realloc(void *mem_address, unsigned int newsize); 语法:指针名=(数据类型*)realloc(要改变内存大小的指针名, ...

  4. JavaScript 内存详解 & 分析指南

    前言 JavaScript 诞生于 1995 年,最初被设计用于网页内的表单验证. 这些年来 JavaScript 成长飞速,生态圈日益壮大,成为了最受程序员欢迎的开发语言之一.并且现在的 JavaS ...

  5. Linux 下Redis集群安装部署及使用详解(在线和离线两种安装+相关错误解决方案)

    一.应用场景介绍 本文主要是介绍Redis集群在Linux环境下的安装讲解,其中主要包括在联网的Linux环境和脱机的Linux环境下是如何安装的.因为大多数时候,公司的生产环境是在内网环境下,无外网 ...

  6. MVC之前的那点事儿系列(2):HttpRuntime详解分析(上)

    文章内容 从上章文章都知道,asp.net是运行在HttpRuntime里的,但是从CLR如何进入HttpRuntime的,可能大家都不太清晰.本章节就是通过深入分析.Net4的源码来展示其中的重要步 ...

  7. shiro过滤器详解分析

    (原) shiro最核心的2个操作,一个是登录的实现,一就是过滤器了.登录有时间再补录说明,这里分析下shiro过滤器怎样玩的. 1.目标 这里会按如下顺序逐一看其实原理,并尽量找出其出处. 先看一下 ...

  8. GBDT 详解分析 转+整理

    GBDT DT 回归树 Regression Decision Tree 梯度迭代 GBDT工作过程实例 需要解释的三个问题 - 既然图1和图2 最终效果相同,为何还需要GBDT呢? - Gradie ...

  9. Javascript异步编程之setTimeout与setInterval详解分析(一)

    Javascript异步编程之setTimeout与setInterval 在谈到异步编程时,本人最主要会从以下三个方面来总结异步编程(注意:特别解释:是总结,本人也是菜鸟,所以总结不好的,请各位大牛 ...

随机推荐

  1. Centos下安装apahce的configure: error: APR not found. Please read the documentation解决办法

    今天从Apache官网上http://httpd.apache.org/下载httpd web服务器,由于我的虚拟机上之前安装过,我先yum remove httpd进行卸载,然后重新安装.我采用的是 ...

  2. win8下everything无法使用的解决方法

    今日我电脑上的Everything打开后都无法使用了,只显示几个分区,重装之后暂时就好了,重启电脑又坏了 解决方法:运行services.msc,启动everything.然后重启everything ...

  3. [Git] Undo a commit that has already been pushed to the remote repository

    If we pushed our changes already to the remote repository we have to pay attention to not change the ...

  4. 使用 HTML5, javascript, webrtc, websockets, Jetty 和 OpenCV 实现基于 Web 的人脸识别

    这是一篇国外的文章,介绍如何通过 WebRTC.OpenCV 和 WebSocket 技术实现在 Web 浏览器上的人脸识别,架构在 Jetty 之上. 实现的效果包括: 还能识别眼睛 人脸识别的核心 ...

  5. 来自Vexels的超棒免费商业相关图标资源 #精选设计素材图标

    如果你也在寻找一些商务相关的图标的话,今天推荐的这套图标资源绝对是你梦寐以求滴 , 首先呢请预览一下效果吧~ 这套来自Vexels的图标包含了28张商务和商业相关的内容,包含了战略,市场,项目,付款等 ...

  6. 视频播放代码 crastr3

    下载:http://down.51cto.com/data/1904974 代码(亲测): <html xmlns="http://www.w3.org/1999/xhtml" ...

  7. asp.net给文件分配自己主动编号,如【20140710-1】

    在开发办公软件的时候,须要给非常多文件什么的东西分配一个编号.是依照日期来的,比方2014.07.10的第一个文件编号就为20140710-1,这一天的第二个文件编号就为20140710-2,以此类推 ...

  8. ZH奶酪:Git简明教程

    这里是原网站:https://try.github.io/levels/1/challenges/1 这篇博文就当是笔记+翻译吧. 几个名词相关 changes:变更 repository:仓库 st ...

  9. JAVA的Spring注入机制事例详解

    一.前言 最近使用Spring里面的依赖注入,比如StudentServiceImple2.java代码: package di.service.imple; import com.mengya.sp ...

  10. HttpLuaModule——翻译(一)

    最近经常使用春哥和小哲老师写的NGINX-LUA,非常苦于没有中文文档,特别是向我这种英文水平实在有限的同学,所以将遇到的模块记录下来,供以后参考!原文:http://wiki.nginx.org/H ...