在无限循环C中运行

问题描述 投票:0回答:3

我正在无限循环中运行,我不知道为什么。我试图调试我的代码,但没有成功。也许有人可以帮我解决这个问题。

void init_list(list* mylist)
{

  mylist->first = NULL;
  mylist->last = NULL;
}



void insert_list(list_element* le, list* mylist)
{

  if(mylist->first == NULL)
  {
    mylist->first = le;
    mylist->last = le;
    return;
  }

  mylist->last->next = le;
  mylist->last = le;
  //printf("Test");

  return;

}

void free_list(list* mylist)
{
    list_element* tmp = mylist->first;
    while(tmp->next != NULL)
    {
      free(mylist->first->password);
      free(mylist->first);
      tmp = tmp->next;
      mylist->first = tmp;
    }
}


void read_data(char* filename, list* mylist)
{
  FILE * file = fopen(filename,"r");

  char line[100];


  while (fgets(line, sizeof(line), file) != NULL)
  {
    char * teile;
    int index;
    teile = strrchr(line, ' ');

    //printf("%s\n",teile);

    index = (int) (teile - line);

    //printf("%d\n",index);

    char password[index+1];

    strncpy(password, line, index);

    password[index] = '\0';

    //printf("%s\n",password);

    list_element * le = malloc(sizeof(list_element));
    le->password = malloc(sizeof(char) * (strlen(password)+1));
    strncpy(le->password,password,(strlen(password)+1));
    le->next = NULL;
    int anzahl = atoi(teile);
    le->count = anzahl;

    //printf("%d %s\n", le->count, le->password);

    insert_list(le, mylist);

  }

  fclose(file);

}

list_element* partition( list* input, list* left, list* right )
{
    list_element * pivot = input->first;


    list_element * tmp;
    for (tmp = pivot->next; tmp != NULL; tmp= tmp->next)
    {
      if((tmp->count) < (pivot->count))
      {
        insert_list(tmp, left);
      }
      else
      {
        insert_list(tmp, right);
      }
    }  
    return pivot;
}

void qsort_list(list* mylist)
{
    list right;
    init_list(&right);
    list left;
    init_list(&left);
    list_element* pivot;

    if(mylist->first != mylist->last)
    {
      pivot = partition(mylist, &left, &right );
      qsort_list(&left);
      qsort_list(&right);


      if(left.first == NULL) 
      {
        mylist->first = pivot;
      } 
      else 
      {
        mylist->first = left.first;
        left.last->next = pivot;
      }
      if(right.first == NULL) 
      {
        pivot->next = right.first;
        mylist->last = pivot;
      } 
      else 
      {
        pivot->next = right.first;
        mylist->last = right.last;
      }     
    }
    return;

}

void print_list(list* mylist)
{
    list_element * current = mylist->first;
    while (current != NULL)
    {
      printf("%s %d \n", current->password, current->count);
      current = current->next;
    }
}

它在insert_list部分中循环。从read_data调用之后。它也仅在最后一次调用该函数时循环。

int main(int argc, char** args)
{
    if (argc != 2)
    {
        printf("USE: %s <Filename>\n",args[0]);
        return 1;
    }
    list mylist;
    init_list(&mylist);
    read_data(args[1],&mylist);
    qsort_list(&mylist);
    printf("Sorted:\n");
    print_list(&mylist);
    free_list(&mylist);
    return 0;
}

typedef struct list_element list_element;

struct list_element {
    char *password;
    int count;
    list_element* next;
};

typedef struct list list;

struct list {
    list_element* first;
    list_element* last;
};

输入如下:

asdfgh 31554
snoopy1 15637
qwertyuiop 24372

编辑:固定输入。Edit2:在注释的帮助下修复了代码。现在,我在分区函数中循环运行。

c memory-management linked-list quicksort singly-linked-list
3个回答
2
投票

这是错误的

char password[index];
strncpy(password, line, index);
password[index] = '\0';

您分配了index个字符,但是使用最后一个语句在数组外部覆盖。您应该使用

进行分配
char password[index+1];

2
投票

函数read_data至少具有三个严重的错误。

首先,您应该检查文件是否成功打开。

第二,您正在使用索引index写入数组密码之外的内容,因为您没有在数组中为终止的零保留内存。

char password[index];

strncpy(password, line, index);

password[index] = '\0';

在此声明中

le->password = password;

列表的所有元素都分配有指向本地数组的指针,该指针在退出函数后将不活动。您必须为每个数据成员le->password动态分配内存。

因此该程序在任何情况下都具有未定义的行为。

功能free_list

void free_list(list* mylist)
{

    free(mylist->first);
    free(mylist);
}

不会释放所有分配的内存。

此外,您在列表设计中也存在逻辑错误。如果您有一个双向链表,则函数insert_list应该在列表的末尾附加一个新节点。否则,将尾节点用于单链列表没有太大意义。


0
投票

这里有个问题。仔细看看您的free_list函数。

void free_list(list* mylist)
{
    list_element* tmp = mylist->first;
    while(tmp->next != NULL)
    {
      free(mylist->first->password);
      free(mylist->first);
      tmp = tmp->next;
    }
    free(mylist);
}

在循环中,第一次设置tmp = mylist-> first,然后释放mylist-> first,然后尝试从tmp中获取'next'指针。 tmp指向的东西现在不见了,因为您刚刚释放了它。

© www.soinside.com 2019 - 2024. All rights reserved.