【问题标题】:Why does my function go into infinite loop sometimes?为什么我的函数有时会进入无限循环?
【发布时间】:2016-06-09 12:08:18
【问题描述】:

我有以下代码。它运行良好。但有时 del 和 ins 函数会进入无限循环,但有时工作正常。 readt 函数工作正常,我仍然将其包含在内以供您参考。我的del和ins有什么问题?有没有内存泄露?

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<math.h>
#include<unistd.h>

struct node
{   int info;
    struct node *link;
};
typedef struct node m;

m *search(int,m*);
m *del(int,m*);
m *ins(int,int,m*);
int posof(int,m*);


int readt(m *t_c,char path[])
{   int t,szt=0;
    FILE *tfile;
    char ch;
    char filename[]="/temp.txt";
    strcat(path,filename);
    tfile=fopen(path,"r");
    if(tfile==NULL)
        exit(0);
    fseek(tfile, 0, SEEK_END);
    szt = ftell(tfile);
    fseek(tfile,0,SEEK_SET);
    if(szt!=0)
    {   while(1)
        {   fscanf(tfile,"%d%c",&t,&ch);
            t_c->info=t;
            t_c->link=(m*)malloc(sizeof(m));
            t_c=t_c->link;
            if(ch==';')
                break;
        }       
    }
    t_c->link=NULL;
    //free(t_c);
    fclose(tfile);
    return 0;
}

m *search(int Noftarget,m *t_c)
{   int i,p1,p2;
    srand(time(NULL));
    for(i=0;i<100;i++)
    {   p1=(1+rand()%(Noftarget));
        p2=(1+rand()%(Noftarget));
        t_c=del(p1,t_c);
        t_c=ins(p1,p2,t_c);
        break;
    }
    return t_c;
}

m *del(int target,m *t_h)
{   m *t_c;
    int j=1,i;
    t_c=t_h;
    i=posof(target,t_h);
    if(i==1)
    {   t_c=t_c->link;
        t_h=t_c;
    }
    else
    {   while(j<i-1)
        {   t_c=t_c->link;
            j++;
        }
        t_c->link=t_c->link->link;
    }
    return t_h;
}

m *ins(int target,int position,m *t_h)
{   int j=0;
    m *swaptarget,*t_c;
    t_c=t_h;
    swaptarget=(m*)malloc(sizeof(m));
    swaptarget->info=target;
    if(position==1)
    {   swaptarget->link=t_c;
        t_h=swaptarget;
    }
    else
    {   while(j<position-2)
        {   t_c=t_c->link;
            j++;
        }
        swaptarget->link=t_c->link;
        t_c->link=swaptarget;
    }
    free(swaptarget);
    return t_h;
}

int posof(int p1,m *t_c)
{   int i=1,a=0;
    while(t_c->link!=NULL)
    {   if(p1==t_c->info)
        {   a=i;
            break;
        }
        t_c=t_c->link;
        i++;
    }
    return a;
}

int main()
{   int Noftarget=8,j,r=1,count=0,noi,szd_n=0,i=0,sz;
    char cwd[200];
    m *t_h;
    getcwd(cwd, sizeof(cwd));
    t_h=(m*)malloc(sizeof(m));
    readt(t_h,cwd);
    t_h=search(Noftarget,t_h);
    free(t_h);
    return 0;
}

临时文件的内容是: 1,2,3,4,5,6,7,8;

【问题讨论】:

  • 检查不好,readt 会在链表中放一个释放的指针,这可能是坏的。
  • 你试过调试你的代码吗??????
  • 是的,我尝试过调试。通过调试,我可以看出它不是在 readt 函数中产生问题,而是在 del 和/或 ins 函数中产生问题。我禁用了 ins 并仅尝试使用 del 并禁用了那里的所有操作,仅保持 posof 功能。但在某些情况下,它甚至不执行 posof。
  • readt() 中,你有一种独特的方式循环fscanf。与其检查文件中是否有“任何字节”并希望输入按预期工作,不如使用来自fscanf 的返回值来控制循环以及“提前退出”。该函数还释放t_c,但main 然后将其再次释放为t_h。太可怕了。
  • @LSG, splint 是一个 source 分析器,它对非注释源的用处非常有限。它猜测函数readt() 获得了通过参数t_c 传递给它的指针的所有权,因此有责任释放它。但这种猜测是错误的。我建议改为使用运行时分析器(例如 valgrind)来检查 实际 内存使用情况。

标签: c memory-leaks malloc infinite-loop free


【解决方案1】:

程序包含内存泄漏。内存在 while 循环内迭代分配,但最后只有一个指针被删除。需要删除所有分配。并且不需要在 ins 函数处释放任何指针,而 del 函数需要对已删除指针的释放操作。修改后的代码在这里:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<math.h>
#include<unistd.h>

struct node
{   int info;
    struct node *link;
};
typedef struct node m;

m *search(int,m*);
m *del(int,m*);
m *ins(int,int,m*);
int posof(int,m*);


int readt(m *t_c,char path[])
{   int t,szt=0;
    FILE *tfile;
    char ch;
    char filename[]="/temp.txt";
    strcat(path,filename);
    tfile=fopen(path,"r");
    if(tfile==NULL)
        exit(0);
    fseek(tfile, 0, SEEK_END);
    szt = ftell(tfile);
    fseek(tfile,0,SEEK_SET);
    if(szt!=0)
    {   while(1)
        {   fscanf(tfile,"%d%c",&t,&ch);
            t_c->info=t;
            t_c->link=(m*)malloc(sizeof(m));
            //printf("%d ",t_c->info);
            t_c=t_c->link;
            if(ch==';')
                break;
        }       
    }
    t_c->link=NULL;
    //free(t_c);
    fclose(tfile);
    return 0;
}
m *search(int Noftarget,m *t_c)
{   int i,p1,p2;
    srand(time(NULL));
    for(i=0;i<100;i++)
    {   p1=(1+rand()%(Noftarget));
        p2=(1+rand()%(Noftarget));
        t_c=del(p1,t_c);
        t_c=ins(p1,p2,t_c);
        break;
    }
    return t_c;
}
m *del(int target,m *t_h)
{   m *t_c;
    int j=1,i;
    t_c=t_h;
    i=posof(target,t_h);
    if(i==1)
    {   free(t_c);
        t_c=t_c->link;
        t_h=t_c;
    }
    else
    {   while(j<i-1)
        {   t_c=t_c->link;
            j++;
        }
        free(t_c->link);
        t_c->link=t_c->link->link;
    }
    return t_h;
}
m *ins(int target,int position,m *t_h)
{   int j=0;
    m *swaptarget,*t_c;
    t_c=t_h;
    swaptarget=(m*)malloc(sizeof(m));
    swaptarget->info=target;
    if(position==1)
    {   swaptarget->link=t_c;
        t_h=swaptarget;
    }
    else
    {   while(j<position-2)
        {   t_c=t_c->link;
            j++;
        }
        swaptarget->link=t_c->link;
        t_c->link=swaptarget;
    }
    return t_h;
}
int posof(int p1,m *t_c)
{   int i=1,a=0;
    while(t_c->link!=NULL)
    {   if(p1==t_c->info)
        {   a=i;
            break;
        }
        t_c=t_c->link;
        i++;
    }
    return a;
}

int main()
{   int Noftarget=7,j,r=1,count=0,noi,szd_n=0,i=0,sz;
    char cwd[200];
    m *t_h;
    getcwd(cwd, sizeof(cwd));
    t_h=(m*)malloc(sizeof(m));
    readt(t_h,cwd);
    print_tsp(t_h);
    t_h=search(Noftarget,t_h);
    print_tsp(t_h);
    while(t_h!=NULL)
    {   free(t_h);
        t_h=t_h->link;
    }
    return 0;
}

由 valgrind 检查,没有任何内存泄漏。

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 2011-11-21
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多