首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 请问一个c语言free函数的使用问题
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cplanxy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-08-22 09:37:11 楼主
    在书上看到过以下例程,对程序最后的free函数的用法有点不明白:既然已经free(current)了,那么current指针所指的内存应该不存在了,怎么还会有接下来的current = current->next呢?
    #include <stdio.h>
    #include <stdlib.h>     
    #include <string.h>     
    #define TSIZE    45

    struct film {
        char title[TSIZE];
        int rating;
        struct film * next;  /* points to next struct in list */
    };

    int main(void)
    {
        struct film * head = NULL;
        struct film * prev, * current;
        char input[TSIZE];

    /* Gather  and store information          */
        puts("Enter first movie title:");
        while (gets(input) != NULL && input[0] != '\0')
        {
            current = (struct film *) malloc(sizeof(struct film));
            if (head == NULL)     
                head = current;
            else                   
                prev->next = current;
            current->next = NULL;
            strcpy(current->title, input);
            puts("Enter your rating <0-10>:");
            scanf("%d", &current->rating);
            while(getchar() != '\n')
                continue;
            puts("Enter next movie title (empty line to stop):");
            prev = current;
        }


        if (head == NULL)
            printf("No data entered. ");
        else
            printf ("Here is the movie list:\n");
        current = head;
        while (current != NULL)
        {
            printf("Movie: %s  Rating: %d\n",
                  current->title, current->rating);
            current = current->next;
        }


        current = head;
        while (current != NULL)
        {
            free(current);
            current = current->next;
        }
        printf("Bye!\n");

        return 0;
    }

    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xkyx_cn
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

    发表于:2008-08-22 09:40:451楼 得分:0
    正确的写法应该用一个临时指针来保存:
    C/C++ code
    // 前面加一个指针定义 struct film *next; current = head; while (current != NULL) { next = current->next; free(current); current = next; }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • k2eats
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:42:482楼 得分:0
    free掉之后,current指向的内存地址还是释放前的,只是这块内存已经标志为可用,
    所以要真正释放采取 free(p);p=NULL;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xiao_ke
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:42:593楼 得分:0
    这个代码存在问题!  也不知道你看得是什么书!
    如果这个程序运行没有问题,那只能说明运气实在是不错。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ww2734
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:43:204楼 得分:0
    以前我也遇到类似的疑惑,
    while (current_head !=NULL)
    {
    Link* p = current_head;
    current_head = current_head->next;
    free(p);
    }
    这样写就对了,至于书上的确搞不清为什么.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:44:075楼 得分:0
    这是某些编译器的特例情形,不在标准范围内,没有可移植性
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hqin6
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:44:406楼 得分:0
    尽信书不如无书!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:51:037楼 得分:0
    lz是在看《C专家编程》
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cplanxy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:59:148楼 得分:0
    我看的是《c primer plus》第5版的489面,我在visual studio c++2008 下运行后没出现错误,但是在运行窗口过后会出现一个“遇到问题需要关闭,我们对此感到。。。”的窗口提示,但是在MinGW Developer studio下运行就正常,我个人也是认为应该建立一个临时的指针来保存current->next值
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • e_sharp
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 09:59:519楼 得分:0
    必须加一个临时指针保存

    free(current); //free后,current指向的内存未知
    current = current->next; //这个地方的行为就不确定了

    引用1楼的代码:
        struct film *next;

        current = head;
        while (current != NULL)
        {
            next = current->next; //先保存
            free(current);
            current = next;
        }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhdsheng
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:01:0910楼 得分:0
    引用 2 楼 k2eats 的回复:
    free掉之后,current指向的内存地址还是释放前的,只是这块内存已经标志为可用,
    所以要真正释放采取 free(p);p=NULL;


    这个很对
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xkyx_cn
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

    发表于:2008-08-22 10:01:4311楼 得分:0
    每个编译器生成的代码不一样,vc可能会把free后的内存填充某个值,再使用就会非法访问,有些编译器可能不这样做

    引用 8 楼 cplanxy 的回复:
    我看的是《c primer plus》第5版的489面,我在visual studio c++2008 下运行后没出现错误,但是在运行窗口过后会出现一个“遇到问题需要关闭,我们对此感到。。。”的窗口提示,但是在MinGW Developer studio下运行就正常,我个人也是认为应该建立一个临时的指针来保存current->next值
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cplanxy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:03:2412楼 得分:0
    还有,假如
    int * p1=(int *)malloc(2*sizeof(int));
    int * p2=p1;
    那么如果要用free的话,是否应该用
    free(p1);
    free(p2);
    呢?

    又如果malloc的是一个新的数组,那么是否有free(p1+2)之类的指令呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • realdragon2
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:12:3013楼 得分:0
    既然已经free掉malloc的内存了,为什么还要再free一次p2呢?

    btw: 你那段小代码是典型的链表释放过程, 不要全部相信书上的.

    引用 12 楼 cplanxy 的回复:
    还有,假如
    int * p1=(int *)malloc(2*sizeof(int));
    int * p2=p1;
    那么如果要用free的话,是否应该用
    free(p1);
    free(p2);
    呢?

    又如果malloc的是一个新的数组,那么是否有free(p1+2)之类的指令呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:14:2214楼 得分:0
    int * p1=(int *)malloc(2*sizeof(int));
    int * p2=p1;
    那么如果要用free的话,
    只能用
    free(p1);

    free(p2);
    之一,同一块内存不能free两次,因为第一次free之后,该块区域可能又被分配给其他地方使用
    再free将引起错误
    malloc只返回分配内存块的首地址,即使是数组,不存在free(p1+2)之类的指令
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • greenbit
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:19:4115楼 得分:0
    引用 2 楼 k2eats 的回复:
    free掉之后,current指向的内存地址还是释放前的,只是这块内存已经标志为可用,
    所以要真正释放采取 free(p);p=NULL;


    严重同意
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cplanxy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:23:5316楼 得分:0
    引用 14 楼 lbh2001 的回复:
    int * p1=(int *)malloc(2*sizeof(int));
    int * p2=p1;
    那么如果要用free的话,
    只能用
    free(p1);

    free(p2);
    之一,同一块内存不能free两次,因为第一次free之后,该块区域可能又被分配给其他地方使用
    再free将引起错误
    malloc只返回分配内存块的首地址,即使是数组,不存在free(p1+2)之类的指令


    那free之后的p1或者是p2的值是什么呢?NULL吗?还是要像2楼一样,加一句p1=NULL;或者p2=NULL;呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • xqls_xqls
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:26:5717楼 得分:0
    引用 4 楼 ww2734 的回复:
    以前我也遇到类似的疑惑,
    while (current_head !=NULL)
    {
    Link* p = current_head;
    current_head = current_head->next;
    free(p);
    }
    这样写就对了,至于书上的确搞不清为什么.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 10:59:2218楼 得分:0
    引用 16 楼 cplanxy 的回复:
    引用 14 楼 lbh2001 的回复:
    int * p1=(int *)malloc(2*sizeof(int));
    int * p2=p1;
    那么如果要用free的话,
    只能用
    free(p1);

    free(p2);
    之一,同一块内存不能free两次,因为第一次free之后,该块区域可能又被分配给其他地方使用
    再free将引起错误
    malloc只返回分配内存块的首地址,即使是数组,不存在free(p1+2)之类的指令


    那free之后的p1或者是p2的值是什么呢?NULL吗?还是要像2楼一样,加一句…

    free之后,p1、p2中值不变,不会自动变为NULL,free操作只是使p1、p2所指向的内存区域归还给系统
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cplanxy
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 11:11:0819楼 得分:0
    free之后,p1、p2中值不变,不会自动变为NULL,free操作只是使p1、p2所指向的内存区域归还给系统

    p1 p2中的值在malloc的时候分配的应该是内存的首位地址值,假如在free后值不变,那么再往P1里面赋值,
    应该可以吧:

    int a = 10;
    *p1 = a;
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • lbh2001
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-08-22 11:14:3820楼 得分:0
    p1 p2中的值在malloc的时候分配的应该是内存的首位地址值,假如在free后值不变,那么再往P1里面赋值,
    应该可以吧:

    int a = 10;
    *p1 = a; //你能保证此时p1指向的地址没有分配给别人,如果赋值,则会导致别人的值莫名其妙的改变

    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved