说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

请问为什么我传入函数的结构所指向的空间会被无端释放调?(内有源码,希望大家帮我看看)

编辑:说三道四文库 发布时间:2018-07-18 04:46
HTML文档下载 WORD文档下载 PDF文档下载
问题写在底下:
//结构定义
typedef struct _itemset {                        /*---a item set(I)---*/
int         cnt;                             /* number of item in item set*/
int         frq;                             /* the frequent of itemset*/
    ITEM        *ifirst;                         /*the point to the fisrt item link in itemset*/
    NODE        *nfirst;                         /* the point to the first tid node*/
struct _itemset   *next;                     /* point to next itemset in LMFI*/
} ITEMSET;                                       /*( a item set )*/

typedef struct _lmfi {                           /*---local maximal frequent itemset---*/
    int         cnt;                             /* count itemset in LMFI*/
ITEMSET     *pitemset;                       /* point to itemset contained in LMFI*/
} LMFI;                                          /*( local maximal frequent itemset)*/
//声明
LMFI *lmfi;
LMFI newlmfi;

//函数代码
void mfi_merge(LMFI *lmfi, LMFI *newlmfi)
{                                                /*---merge lmfi and newlmfi to one lmfi---*/
int         k,l;                             /* loop variable*/
ITEMSET     *ploopnewits;                    /* loop itemset link in newlmfi*/
ITEMSET     *ploopits;                       /* loop itemset link in lmfi*/
ITEMSET     *ptemp;                         
ITEM        *pitem;                          /* parameter of its_contain(),no use in this function*/
bool        flag = FALSE;                    /* ture if ploopits contain ploopnewits*/
int         count ;                          /* itemset count in newlmfi*/
ploopnewits = newlmfi->pitemset;             /* get itemset link*/
ploopits = lmfi->pitemset;                   
count = newlmfi->cnt;                        /* get count of itemset in newlmfi*/
for(k=0;k<count;k++)             
{                                            /* check each itemset in newlmfi*/
for(l=0;l<lmfi->cnt;l++)
{                                        /* each its(newlmfi) vs all its(lmfi)*/
if(flag = its_contain(ploopits,ploopnewits,&pitem)) /* loopits contain loopnewits*/
break;                           /* don't need contain this loopnewits*/
ploopits = ploopits->next;  /* prepare check next loopits*/
}
if(!flag)                                /* all its in lmfi don't contain loopnewits*/
{
            ptemp = ploopnewits->next;           /* get next its in newlmfi*/
mfi_addits(lmfi,ploopnewits);        /* add loopnewits in lmfi*/
ploopnewits = ptemp;                  /* ploopnewits to next its*/
}
else                                     /* loopnewits contain in lmfi*/
{
ptemp = ploopnewits;                 /* get current no used itemset*/
ploopnewits = ploopnewits->next;     /* check next its in newlmfi*/ 
            its_free(ptemp);                     /* free no used itemset*/
}
flag = FALSE;                            /* reain flag*/
}
}                                                /* mfi_merge()*/


//我的函数调用
mfi_merge(lmfi,&newlmfi);

//问题是,当我调用mfi_merge()之前mewlmfi.pitemset指向一个ITEMSET类型的链表,没有问题都很正确,当我单步运行进入函数,newlmfi->pitemset(注意此时的newlmfi已经是函数调用的参数,为一个指针了)所指向的空间就被释放掉了,里面的值全部乱掉,请问是怎么回事呢? 
ps:但是newlmfi->cnt 的值正确,newlmfi->pitemset这个指针所指的地址是没有变的,只是这个地址的空间好像被释放了。

真的很想知道,谢谢大家了!
源代码里面的注释转贴过来的时候有点问题,对不起了,看的时候可能有点难
void mfi_merge(LMFI *lmfi, LMFI *newlmfi)
{                                                
int         k,l;                             
ITEMSET     *ploopnewits;                    
ITEMSET     *ploopits;                       
ITEMSET     *ptemp;                         
ITEM        *pitem;                          
bool        flag = FALSE;                    
int         count ;                          
ploopnewits = newlmfi->pitemset;             
ploopits = lmfi->pitemset;                   
count = newlmfi->cnt;                        
for(k=0;k<count;k++)             
{                                            
for(l=0;l<lmfi->cnt;l++)
{                                        
     if(flag = its_contain(ploopits,ploopnewits,&pitem)) 
break;                                           ploopits = ploopits->next;
}
if(!flag)                                
{
                           ptemp = ploopnewits->next;           
mfi_addits(lmfi,ploopnewits);        
ploopnewits = ptemp;                  
}
else                                     
{
ptemp = ploopnewits;                 
ploopnewits = ploopnewits->next;      
                            its_free(ptemp);                     
}
flag = FALSE;                            
}
}                                              

好了,我把注释全删了,不顾我想这个问题和函数本身的问题不大
//结构定义
typedef struct _itemset {                        
int         cnt;                             
int         frq;                            
    ITEM        *ifirst;                         
    NODE        *nfirst;                         
struct _itemset   *next;                     
} ITEMSET;                                       

typedef struct _lmfi {                           
    int         cnt;                            
ITEMSET     *pitemset;                      
} LMFI;                                         
//声明
LMFI *lmfi;
LMFI newlmfi;
结构的定义我也删了注释
看在我这么辛苦的分上,有人来帮帮忙撒 !
提供你一个可能的情况!

mfi_addits(lmfi,ploopnewits);
如果你的lmfi在程序里要改变所指的值,最好定义 mfi_addits时它的参数是*& 的.
mfi_addits(LMFI*& ,...); 
函数在传入指针的时候是类似这样的:再建立一个指针指向传入的指针指向的地方.
即:p----->[]      fun(Type* q);
          ^
在fun中q__|
如果你改了q的指向,当fun结束时q就撤销了,但p还是指向原来的地方.如果你把原来的地方释放掉,就会出现你的情况了.所以要用*& refference to pointer.
我只是提供给你一个可能的情况.具体你还要分析.
谢谢snipersu
不过,我觉得现在的问题不是这个函数的是问题,newlmfi在传入mfi_merge()之前的值都是正确的,进入mfi_merge()的时候,newlmfi->cnt和newlmfi->pitemset的值没有变,变的是newlmfi->pitemset所指向空间的值!!!,所以我在想有什么情况下进入一个子函数会释放掉已经分配的链表空间。但单单是进入一个函数,又没有任何对指针的操作,怎么会就无缘无故的出现问题呢?
好象函数没错,是不是你使用他时弄错了。

自己查查,应该是小问题。
要看看调用函数的定义,你的newlmfi是存放在什么的?我怀疑你的newlmfi是另一个函数中的局部变量,这样的话,可能newlmfi已经失效,但是在进入函数前还没有被覆盖,在进入后newlmfi所在的stack空间被部分覆盖,这时会产生你说的问题

关注,我也曾在gcc上遇到这样的问题,但同样的代码在devcpp上却没有问题
支持 Tommy 的猜测。
关于tommy说的 
在我的代码中定义的函数是
int LMFI_backtrack(ITEMSET *itemset,COMBINESET *combineset,LMFI *lmfi,int level,int supcnt)
{
    ...
     LMFI       newlmfi;                         /* lmfi(l+1)*/
    ...
     newlmfi.cnt =0; 
     newlmfi.pitemset = NULL; 
     ...
     mfi_addits(lmfi,&newitemset);//对传进来的lmfi进行添加链表元素
     ...
     LMFI_backtrack(&newitemset,&newcombineset,&newlmfi,level+1,supcnt);
     //递归调用,当然是在一定条件下的递归了
     mfi_merge(lmfi,&newlmfi);//递归返回后将newlmfi和lmfi合并,准备向上一级返回
     ...
}//我的问题是在递归结束(我的例子是三层递归),第一次返回时出现的问题。
请给出递归结束的条件,问题可能出在递归上,好好看看在函数LMFI_backtrack()中有关lmfi的语句是怎么操作的,是否更改limf->pitemset的值,还有,递归里面newlmfi的空间在每层递归结束后都会被释放掉,看看是否与此有关。
LMFI_backtrack中的

mfi_addits(lmfi,&newitemset);//对传进来的lmfi进行添加链表元素

newitemset是从哪来的?是否LMFI_backtrack中定义的局部变量?如果是的话,你就是将一个局部变量加到链表中,这个结点在返回后就失效了。
Tommy!!终于被你找到问题啦!
 太谢谢你了!
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘