free()函数释放一段分配的内存之陷阱
朋友们对malloc函数应该是比较熟悉了,此函数功能是分配一段内存地址,并且将内存地址给一个指针变量,最后记得再调用free函数释放这段内存地址就可以了,标准的流程对吧,好像没什么问题。但是按照此标准流程,下面的程序却有个奇怪的现象:
#include <stdio.h>
#include <string.h>
#include <malloc.h> int main()
{
char *p = (char *)malloc(6); if(NULL == p)
{
printf("内存分配失败!\n");
return -1;
}
else
{
memset(p, 0, 6);
strcpy(p, "12345");
*(p + 5) = '\0'; while( ('4' != *p) && ('\0' != *p) )
{
p++;
} free(p);
} return 0;
}
程序不难,功能就是使用malloc函数分配一段内存空间,用于存放6个字符数据”123456“,最后使用free函数来释放这段内存地址。可是一运行结果就报错了,如下:
我奇了个怪的!
调试吧!调着调着,我了个去,我发现malloc函数分配的这一段内存空间的起始地址是”0x00382c88“,也就是说指针变量p的值是”0x00382c88“,地址为”0x00382c88“的一段内存存放着字符‘1’。经过while循环后,指针变量p指向字符‘4’了,而字符‘4’在内存中的地址是”0x00382c8b“,也就是指针p的值是”0x00382c8b“。此时跳出while循环,紧接着调用free函数,我的原意是想释放从”0x00382c88“开始的内存区域,现在变成释放了从”0x00382c8b“开始的内存区域,因此报了这个错!
好了,找到原因了,那就修改下程序吧。一种解决方法是使用另一个指针变量q, q初始也指向字符‘1’,在while循环中使用指针变量q而不是p,程序修改如下:
#include <stdio.h>
#include <string.h>
#include <malloc.h> int main()
{
char *p = (char *)malloc(6);
char *q = NULL; if(NULL == p)
{
printf("内存分配失败!\n");
return -1;
}
else
{
q = p;
memset(p, 0, 6);
strcpy(p, "12345");
*(p + 5) = '\0'; while( ('4' != *q) && ('\0' != *q) )
{
q++;
} free(p);
} return 0;
}
这样,在while循环中指针变量q最终指向字符‘4’,而指针变量p依然指向字符‘1’,也就是指针变量p的值依旧是”0x00382c88“,也就是分配的内存的起始地址!
本文代码是在微软的VC6.0上编译与运行。
free()函数释放一段分配的内存之陷阱的更多相关文章
- Java JNA (五)—— 释放Memory对象分配的内存
Java进程的内存包括Java NonHeap空间.Java Heap空间和Native Heap空间. JNA中的Memory对象是从Native Heap中分配空间.但java的GC是针对Java ...
- EXE中释放DLL中分配的内存
在DLL中分配的内存,如果到其调用者中释放,可能会出现CRASH的情况,其原因在于: 在DLL中的Code Generation如果是采用了MT(静态加载LIBCRTD.LIB)在该库中维护了一个al ...
- delphi.memory.分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同,内存分配函数
来自:http://www.cnblogs.com/qiusl/p/4028437.html?utm_source=tuicool&utm_medium=referral ---------- ...
- 不能返回函数内部new分配的内存的引用
以前在开发电子秤接口动态库时,曾尝试在用于获取重量的函数外面定义一个字符串指针,然后作为参数传入函数内部,然后在函数内部new,用来输出函数执行过程中发生的错误.但是总是出错,没有找到原因,后来无意中 ...
- 关于c语言内存分配,malloc,free,和段错误,内存泄露
1. C语言的函数malloc和free (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数 void * malloc(size_t size ...
- c++之函数值传递和引用传递解析----关键在于理解函数return的实现机制(内存分配)
函数调用过程解析 func里的a存储在调用fun函数时开辟的栈空间里,这块栈只在调用func时对func可用,调用结束后返回的a,其实是暂存在寄存器里的(一般情况下是eax),而返回到main里时,m ...
- C++ 动态分配 和 内存分配和内存释放
动态分配 动态分配可以说是指针的关键所在.不需要通过定义变量,就可以将指针指向分配的内存.也许这个概念看起来比较模糊,但是确实比较简单.下面的代码示范如何为一个整数分配内存: int *pNumber ...
- DLL分配的内存如何在EXE里面释放
总结下面几个要点: 1. 保证内存分配和清除的统一性:如果一个DLL提供一个能够分配内存的函数,那么这个DLL同时应该提供一个函数释放这些内存.数据的创建和清除应该在同一个层次上. 曾经遇到过这样的例 ...
- 在用free()函数释放指针内存时为何要将其指针置空
在通过free()函数释放指针内存之后讲其指针置空,这样可以避免后面的程序对与该指针非法性的判断所造成的程序崩溃问题.释放空间,指针的值并没有改变,无法直接通过指针自身来进行判断空间是否已经被释放,将 ...
随机推荐
- DLL编写与调用全解
DLL编写与调用全解 DELPHI学习 2008-12-23 22:52 阅读8 评论0 字号: 大 中 小 第一章 为什么要使用动态链接库(DLL) top 提起DLL您一定不会 ...
- block-chain java source
source:github.com/enderlu/Swiftglobal ide:idea ,要安装Lombok plugin 配置: -Dspring.config.location=file:D ...
- 【MVC 笔记】MVC 自定义 Attribute 属性中的猫腻
原想在 MVC Action 上加一个自定义 Attribute 来做一些控制操作,最先的做法是在自定 Attribute 中定义一个属性来做逻辑判断,可惜事与愿违,这个属性值居然会被缓存起来,于是于 ...
- enum 枚举一般用法 dotnet
public enum Demo { [Description("Moning描述")] Moning = , [Description("Afternoon描述&quo ...
- delphi 获取当前进程的cpu占用率
type TProcessCpuUsage = record private FLastUsed, FLastTime: Int64; FCpuCount:Integer; publ ...
- WIN10以后如果Manifest中不写支持WIN10的话,获取版本号的API获取的是6
if TOSVersion.Major = 10 then // 高版本的Delphi(比如Berlin)可以这样写 ShowMessage('Windows 10'); 或者: if Win32M ...
- js打印指定元素内容
var v = document.createElement("div"); //向v中追加打印数据,可以将界面的元素追加进来 var h = window.open(" ...
- T4随记
关于T4模板的信息我就不赘述了,百度一大堆 MSDN的介绍 https://msdn.microsoft.com/zh-cn/library/bb126478.aspx 下面是简单的一个示例,从类中获 ...
- 桌面程序阻止Windows关机(使用Message.Result取得DefWindowProc API函数的返回值,非常重要)
Windows Client 客户端在关机,不外乎两种情况: 1. 没有处理 Windows 关机消息: 2.处理了关机消息,但是超时了: 上面这两种情况,都会让Windows 关不了机.在现实生活中 ...
- HTML连载12-体验CSS
一.通过标签来修改标签有哪些缺点: (1)需要记忆那些标签有哪些属性 (2)若该标签没有这个属性,则修改失败 (3)需求变更,需要修改大量的代码 (4)HTML标签及用于添加语义,与我们的定义不相符 ...