#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mainc26.h"
struct TelPhone{
char name[];
char TelNumber[];
struct TelPhone* next;
};
int mainc26()
{ setbuf(stdout, NULL);
//fflush(stdout);
struct TelPhone *head = NULL;
struct TelPhone *pre,*current;
char input[];
printf("请输入联系人的姓名:\n");
fflush(stdout);
while(gets(input) != NULL && input[] != '\0')
{
current = (struct TelPhone*)malloc(sizeof(struct TelPhone));
if(head == NULL)
head = current;
else
pre->next = current;
current->next = NULL;
strcpy(current->name,input);
printf("请输入联系人的电话号码:\n");
scanf("%s",current->TelNumber);
while(getchar() != '\n')
continue;
printf("请输入下一个联系人(空行则退出):\n");
pre = current;
}
if(head == NULL)
printf("电话里面没有储存任何数据:");
else
puts("通讯录:");
current = head;
while(current != NULL)
{
printf("%s:%s\n",current->name,current->TelNumber);
current = current->next;
}
current = head;
int n=;
while(current != NULL)
{
n++;
printf("this is %d time \n",n);
free(current);
current=NULL;
printf("cur.name %s ,",current->name);
printf("cur.teln %s ,",current->TelNumber);
// printf("cur.name %p ,",current->next);
printf("\n");
current = current->next;
}
return ;
}

在 line 53中 使用free(current) ,这里似乎是将current的内存释放,然后实际上,这里的释放后,其内存信息已经存在,

如果将line 54的current=null,注释,该程序仍能正确运行,并通过该链表将内存释放掉,而实际上这种问题时错误的。

通过百度,我查到

问题如下:

 代码如下:
#include <stdio.h>
#include <stdlib.h> struct test
{
int a;
struct test *next;
};
int main()
{
struct test test0={};
struct test *test1 = (struct test *)malloc(sizeof(struct test));
test1->a=;
test1->next = &test0;
free(test1);
printf("%d %d",test1->a,(*test1->next).a); }
输出test1->a为0 ,(*test1->next).a为10 说明结构体里的变量a已经被free释放掉了,而test1的指针next却还可以被访问

解答如下

free函数,实际上做的事情不是真正的释放内存。
首先你要清楚,内存是由操作系统来管理的(操作包括分配、释放等)。
系统中的内存在c语言分配内存机制上被分为很多个块,c的底层代码用数据结构chunk来表示。chunk中有一个标志位,用来表示该内存块是否为待分配或者已分配状态。每一次调用malloc,这个标志位会被设置1(好像是1,记不太清楚了),调用free时被设置为0. 操作系统的内存管理机制会根据这个值来分配和释放内存。
也就是说调用free的时候,只是设置了这个标志位(当然还做了其他事,就你这个问题而言,只讨论这个),而内存还原封不动的在那里。所以,当你在系统真正释放这个内存之前再次访问这个地址,你会得到你想要的结果。
说明,“输出test1->a为0”,这个的原因可能是free的时候,设置chunk块的标志位时,覆盖了a的值。chunk数据结构中,第一个字节的前8位是标志位,后面还有24位也有各自的用处。具体是什么导致a的值为0的,你有兴趣的话,你可以自己去研究。可以去阅读linux的glibc源码。
"(*test1->next).a为10",就简单了。next偏移struct test所占内存的“头(head)”距离较远,free的时候的一些设置值的操作没有影响到,能访问到这个指针的值,并且test0还在函数栈中完整保留,自然就能访问到了。 P.S c/C++的malloc/free和new/delete都有这个特性,所以编程的时候要养成一个良好习惯,在调用free和delete的时候要将指针赋值为NULL,如:
free(ptr);
ptr=NULL;
或者
delete ptr;
ptr=NULL;

所以这里和回答的问题比较相符,
实际上free(current)以后,其内存的实际内容 并没有被释放,仍然可以使用,但这样是应该,
应该讲内存释放后的变量赋值为NULL.
那么单项链表的内存该如何释放呢?? 可以参考如下的代码,将其释放
     //释放内存
struct TelPhone * temp;
while(current != NULL)
{
n++; printf("this is %d time \n",n);
printf("cur.name %s ,",current->name);
printf("cur.teln %s ,",current->TelNumber);
printf("cur.name %p ,",current->next);
printf("\n"); temp=current;
current=current->next;
free(temp);
temp=NULL;
}
												

关于free的使用疑惑的更多相关文章

  1. Atitit 图像处理的心得与疑惑 attilax总结

    Atitit 图像处理的心得与疑惑 attilax总结 1.1. 使用类库好不好??还是自己实现算法1 1.2. 但是,如果遇到类库体积太大,后者没有合适的算法,那就只能自己开发算法了1 1.3. 如 ...

  2. 每日一记-mybatis碰到的疑惑:String类型可以传入多个参数吗

    碰到一个觉得很疑惑的问题,Mybatis的parameterType为String类型的时候,能够接收多个参数的吗? 背景 初学Mybatis的时候,看的教程和书籍上都是在说基本的数据类型如:int. ...

  3. 解决上一篇jquery中on的疑惑

    内容都是来自:http://www.365mini.com/page/jquery-on.htm.这里做一下收藏.文章的最后  疑问和解答可以解决所有的疑惑  看了之后能更好的整篇文章. on()函数 ...

  4. ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?

    前言 事情不太多时,会时不时去看项目中同事写的代码可以作个参考或者学习,个人觉得只有这样才能走的更远,抱着一副老子天下第一的态度最终只能是井底之蛙.前两篇写到关于断点传续的文章,还有一篇还未写出,后续 ...

  5. Python处理json格式的数据文件(一些坑、一些疑惑)

    这里主要说最近遇到的一个问题,不过目前只是换了一种思路先解决了,脑子里仍然有疑惑,只能怪自己太菜. 最近要把以前爬的数据用一下了,先简单的过滤一下,以前用scrapy存数据的时候为了省事也为了用一下它 ...

  6. SQL Server中的索引结构与疑惑

    说实话我从没有在实际项目中使用过索引,仅知道索引是一个相当重要的技术点,因此我也看了不少文章知道了索引的区别.分类.优缺点以及如何使用索引.但关于索引它最本质的是什么笔者一直没明白,本文是笔者带着这些 ...

  7. python的正则表达式 re-------可以在字符串前加上 r 这个前缀来避免部分疑惑,因为 r 开头的python字符串是 raw 字符串,所以里面的所有字符都不会被转义

    正则表达式使用反斜杆(\)来转义特殊字符,使其可以匹配字符本身,而不是指定其他特殊的含义.这可能会和python字面意义上的字符串转义相冲突,这也许有些令人费解.比如,要匹配一个反斜杆本身,你也许要用 ...

  8. jquery 清除动画队列不疑惑

    $(this).siblings().stop().fadeTo(200, 0.3); jquery动画存在一个队列, 会把事件产生的动画 放在一个队列中,当来不及执行这些事件队列的时候,会在事件结束 ...

  9. 对Joint Training of Cascaded CNN for Face Detection一文的几点疑惑

    最近读了Joint Training of Cascaded CNN for Face Detection这篇论文,论文中把之前人脸检测使用到的cascade cnn,从分开训练的模式,改为了联合训练 ...

  10. 关于flume中的几个疑惑

    文章发自http://www.cnblogs.com/hark0623/p/4205756.html  转载请注明 flume越用越有一些疑惑,这个月中按计划是要阅读flume源码的,我希望能解决我的 ...

随机推荐

  1. bladex数据字典关联基础表

    一:引用import {getDeptTree} from "@/api/system/dept";二: { label: "部门id", prop: &quo ...

  2. ASP.NET Core 之跨平台的实时性能监控

    前言 前面我们聊了一下一个应用程序 应该监控的8个关键位置. . 嗯..地址如下: 应用程序的8个关键性能指标以及测量方法 最后卖了个小关子,是关于如何监控ASP.NET Core的. 今天我们就来讲 ...

  3. war包部署在tomcat下,使用windows service服务方式启动tomcat服务器,在包含调用dll的模块,报dll找不到问题的解决办法

    问题描述: 开发了一个需要调用dll的java web程序,在idea开发环境下运行调试没问题,可以正常运行,在tomcat/bin下,运行批处理startup.bat,启动tomcat服务器,也可以 ...

  4. vs解决方案中添加文件夹

    一般我们在github上面看到的项目结构基本都是把项目放到src文件夹中,test放测试 查了半天也没查到这个是怎么产生的...这边只能用比较笨的方法来完成. 解决方法中是允许我们添加解决方案文件夹, ...

  5. Openresty 健康检查

    ## 指定共享内存 lua_shared_dict healthcheck 1m; ## 在worker初始化过程中,启动定时器,进行后端结点的检查 init_worker_by_lua_block ...

  6. 后端&前端零碎知识点和注意问题

    后端 1. Spring自带的MD5加密工具类 import org.springframework.util.DigestUtils; String md5Password = DigestUtil ...

  7. MyBatis参数条件查询传入的值为0时的判断

    MyBatis条件查询对字段判断是否为空一般为: <if test="testValue!=null and testValue != ''"> and test_va ...

  8. 洛谷--P1028 数的计算(递推)

    题意:链接:https://www.luogu.org/problem/P1028 先输入一个自然数n (n≤1000) , 然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自 ...

  9. 递归实现全排列python

    python递归实现"abcd"字符串全排列 1.保持a不动,动bcd 2.保持b不动,动cd 3.保持c不动,动d def pailie(head="",st ...

  10. Python3 - Bytes类型

    Python3 新增 bytes 类型,是指一堆字节的集合,十六进制表现形式,两个十六进制数构成一个 byte ,以 b 开头的字符串都是 bytes 类型. 计算机只能存储二进制,字符.图片.视频. ...