朋友们对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()函数释放一段分配的内存之陷阱的更多相关文章

  1. Java JNA (五)—— 释放Memory对象分配的内存

    Java进程的内存包括Java NonHeap空间.Java Heap空间和Native Heap空间. JNA中的Memory对象是从Native Heap中分配空间.但java的GC是针对Java ...

  2. EXE中释放DLL中分配的内存

    在DLL中分配的内存,如果到其调用者中释放,可能会出现CRASH的情况,其原因在于: 在DLL中的Code Generation如果是采用了MT(静态加载LIBCRTD.LIB)在该库中维护了一个al ...

  3. delphi.memory.分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同,内存分配函数

    来自:http://www.cnblogs.com/qiusl/p/4028437.html?utm_source=tuicool&utm_medium=referral ---------- ...

  4. 不能返回函数内部new分配的内存的引用

    以前在开发电子秤接口动态库时,曾尝试在用于获取重量的函数外面定义一个字符串指针,然后作为参数传入函数内部,然后在函数内部new,用来输出函数执行过程中发生的错误.但是总是出错,没有找到原因,后来无意中 ...

  5. 关于c语言内存分配,malloc,free,和段错误,内存泄露

    1.   C语言的函数malloc和free (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数        void * malloc(size_t size ...

  6. c++之函数值传递和引用传递解析----关键在于理解函数return的实现机制(内存分配)

    函数调用过程解析 func里的a存储在调用fun函数时开辟的栈空间里,这块栈只在调用func时对func可用,调用结束后返回的a,其实是暂存在寄存器里的(一般情况下是eax),而返回到main里时,m ...

  7. C++ 动态分配 和 内存分配和内存释放

    动态分配 动态分配可以说是指针的关键所在.不需要通过定义变量,就可以将指针指向分配的内存.也许这个概念看起来比较模糊,但是确实比较简单.下面的代码示范如何为一个整数分配内存: int *pNumber ...

  8. DLL分配的内存如何在EXE里面释放

    总结下面几个要点: 1. 保证内存分配和清除的统一性:如果一个DLL提供一个能够分配内存的函数,那么这个DLL同时应该提供一个函数释放这些内存.数据的创建和清除应该在同一个层次上. 曾经遇到过这样的例 ...

  9. 在用free()函数释放指针内存时为何要将其指针置空

    在通过free()函数释放指针内存之后讲其指针置空,这样可以避免后面的程序对与该指针非法性的判断所造成的程序崩溃问题.释放空间,指针的值并没有改变,无法直接通过指针自身来进行判断空间是否已经被释放,将 ...

随机推荐

  1. asp.net文件流下载的代码摘要

    try { var workbook = new XLWorkbook(); if (Workbook != null) { workbook = Workbook; } if (this.Expor ...

  2. Win10《芒果TV》更新v3.6.0秋收版:新增追剧磁贴、记忆续播、跳转列表

    热血青春,唱响革命战歌,<秋收起义>正在芒果TV热播,Win10版<芒果TV>更新v3.6.0秋收版,新增追剧磁贴.记忆续播.跳转列表. Win10版<芒果TV>V ...

  3. 零元学Expression Blend 4 &ndash; Chapter 21 以实作案例学习MouseDragElementBehavior

    原文:零元学Expression Blend 4 – Chapter 21 以实作案例学习MouseDragElementBehavior 本章将教大家如何运用Blend 4内建的行为注入元件「Mou ...

  4. SynchronizationContext笔记

    SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型 ...

  5. 安卓ImageButton圆角按钮设置

    首先图片要做成圆角的,使用美图秀秀,这个不多说. 之后使用设置了圆角的按钮,效果有缺陷,按钮会有灰色的边角. 类似这样: 去掉的方法是将layout的  android:src="@draw ...

  6. Delphi7 时钟(使用了多个自定义组件)

    http://download.csdn.net/detail/akof1314/3073289

  7. Mac App Store应用签名和pkg签名,查看签名

    App签名 只有用苹果颁发的证书签名的应用才能在App Store上进行销售,所以我们开发的应用必须打上签名. 签名有两种方式,一是使用Xcode,在配置里面设置签名,编译出来的app就有了签名:二是 ...

  8. mac下实现代码远程同步

    近期将办公电脑从windows换成了mac,以前一直用windows,在windows下面将代码同步到远程的开发机,zend studio有一些内置的工具,但mac下的zend stduio没有了这个 ...

  9. CSS3 Maker提供了10个最为常用的CSS3属性在线生成工具

    CSS3 Maker提供了10个最为常用的CSS3属性在线生成工具,比如说border-radius.gradient.transfrom.animation.transition.rgba.text ...

  10. 《Windows via C/C++》学习笔记 —— 设备I/O之“同步的设备I/O”(系列文章)

    前面曾经讲过,设备I/O的方式有两种:同步和异步.本篇介绍一下同步设备I/O.主要涉及到两个函数:ReadFile和WriteFile. 不要被这两个函数的名称迷惑,不仅可以将这两个作用于文件,也可以 ...