| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1330 人关注过本帖
标题:求个关于链表释放的问题 。
取消只看楼主 加入收藏
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用bccnyouke在2012-11-26 22:53:20的发言:

就是写个提示性的宏,告诉你区别错误/正确,免的以后再犯
开的空间小了,再写就溢出了,malloc链的结构给你破坏了
free的时候自然就错了,有兴趣可以看看malloc源码

呵呵 这个有点奇怪耶 用 sizeof(LinkList)还是能创建并输出一个链表 但是只有free时才出现错误
既然malloc链的结构给破坏了为什么还能正常的做一部分事情?
这算不算一种缺陷?

梅尚程荀
马谭杨奚







                                                       
2012-11-26 23:08
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用bccnyouke在2012-11-26 23:25:03的发言:

我说你不懂,你还不谦虚,你就是要问为什么free才错是吧?
你一直申请当然没问题,malloc不会去验证你这次申请是不是破坏了之前block的结构
你可能又要问为什么打印是对的?因为你指针指向的那片区域存的就是你的数据,没问题
只不过,你没意识到因为overflow的关系,block的结构已经完蛋了,free又不知道你破坏了
block结构,没有合适的结构去释放,还可能对?
本来呢,我看你在汇编版块学习,说明你还是想提高自己能力的,才回你的
现在看来,可能多此一举了,呵呵

真心谢谢你啊 我真不懂 就是想问个明白 如果那里有言语冒犯还请多多海涵呐
 书上(如数据结构链表的讲解)对这方面的东西都是擦边球 我查资料的能力比较低找半天没弄明白
发帖求助是真心的 请您多多指教 。

这些东西是不是涉及到内存管理? 我还比较陌生 汇编学来也是坑坑洼洼的


梅尚程荀
马谭杨奚







                                                       
2012-11-26 23:35
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用bccnyouke在2012-11-26 23:53:27的发言:

以后可以找些open source的malloc分析分析,可能一下子没法全看懂,慢慢来,先把指针弄明白了,你还是有潜力的,相信自己
至少你问的这个问题,自己可以完全靠调试弄明白,碰到这种问题,尽量把代码缩小,减小到几句,调一调就出来了
比如说一个申请,一个释放,连续2个申请,连续两个释放,代码不长,一定要自己耐心调一调

恩 谢谢你的建议 !!

梅尚程荀
马谭杨奚







                                                       
2012-11-27 00:04
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 24楼 TonyDeng
你的意思是要始终注意检查malloc的返回值吧

现在明白我源程序给一个节点开的空间是小了 malloc要人为地计算和注意分配的大小 有点麻烦哦

梅尚程荀
马谭杨奚







                                                       
2012-11-27 00:09
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
以下是引用TonyDeng在2012-11-27 00:14:54的发言:

要分配给某种类型的指针,在C++中必须对malloc()的返回值进行强制类型转换给对方,编译器会给你进行内存对齐,否则是不会做的,因为这个函数的返回值本身是void*,而你的接收指针不是void*。你那代码中所进行的强制类型转换,自己把它还原了看是不是SNODE*。好好的数据类型SNODE不用,你偏要用那个被代换过的*LINKLIST。

typedef struct Node
{
    int num;
    struct Node *next;
}SNode, *LinkList;

这个东西,在C++中是不需要写typedef的,下面这样就简明扼要了:

struct SNode
{
    int num;
    struct Node *next;
};

这样,SNode就是一个经典意义上的数据类型,你可以使用SNode或SNode*,不需要再搞什么类型别名。有int就够了,也不需要再给int*起一个类型名称,像API中那些PINT之类的东西,其实没什么必要。

谢谢 老大给俺讲这么多 知道了不少东西 我再琢磨琢磨
现在改习惯了 1点之前必须睡觉 早上好早早起来锻炼身体! 呵呵 。
洗脸 漱口 泡脚 睡觉去 哈哈
老大 晚安。

梅尚程荀
马谭杨奚







                                                       
2012-11-27 00:30
有容就大
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:东土大唐
等 级:版主
威 望:74
帖 子:9048
专家分:14309
注 册:2011-11-11
收藏
得分:0 
回复 19楼 bccnyouke
去搞了个小实验 想验证下malloc分配的BLOCK结构
发现个有趣的现象
程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct LNode
{

    struct LNode *next;
    int num;
    float fl;
    double du;
}LNode, *LinkList;


LNode* ApplyMem(LNode *head)
{
    LNode *p;
    int i, j;
    i = sizeof(LinkList);
    j = sizeof(LNode);
    printf("%d %d\n", i, j); //输出的是i, j
    if (NULL == head)
    {
        head = (LNode *)malloc(1 * sizeof(LinkList));

        if (!head)
        {
            printf("Apply fail!\n");
            return NULL;
        }
    }
    head->next = NULL;
    head->num = 1;
    //head->ch = 'a';
    head->fl = 1.2;
    head->du = 22.0;

    p = (LNode *)malloc(1 * sizeof(LinkList));
    if (!p)
    {
        printf("Apply fail!\n");
        return NULL;
    }
    p->num = 2;
    //p->ch = 'b';
    p->fl = 2.4;
    p->du = 54.0435;

    p->next = head->next;
    head->next = p;
    return head;
}

void FreeMem(LNode *head)
{
    LNode *p;
    while (NULL != head)
    {
        p = head;
        head = head->next;
        free(p);
    }
}

void PrintList(LinkList head)
{
    LinkList p;
    p = head;
    while (NULL != p)
    {
        printf("%d %f %f", p->num, p->fl, p->du);
        p = p->next;
    }
}

int main(void)
{
    LNode *head = NULL;
    head = ApplyMem(head);
    PrintList(head);
    //free(head);
    head = NULL;
    return 0;
}
实验时先不释放。
我上面这个程序运行也错误 如果改成(LNode *)malloc(2 * sizeof(LinkList));就能打印
但是2 * sizeof(LinkList) = 8也远小于LNode的实际大小(24)所以当添加上free后报错。
为什么会这样
后来查了下资料 原来malloc(STRUCT_SIZE)分配的内存实际要比STRUCT_SIZE要大
即在用户申请的空间前malloc隐式的分配了若干个字节用来写入被分配内存的信息 free函数就是
通过这个东西来释放内存的
如果用户申请的内存比结构体的size小了 在给结构体赋值时填充的内容会占用‘分配内存的信息’的
那块空间 即BLOCK结构被破坏 free必然出错。如果还没超出整个分配内存,打印没问题,如果超出了
那么打印也无法进行。
这个算是我的理解 具体的细节还不甚了了 不知道理解的对不对?

梅尚程荀
马谭杨奚







                                                       
2012-11-28 07:49
快速回复:求个关于链表释放的问题 。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019448 second(s), 8 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved