【问题标题】:Running in an Infinite Loop C在无限循环中运行 C
【发布时间】:2020-05-19 14:36:58
【问题描述】:

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

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:在 cmets 的帮助下修复了代码。现在我在我的分区函数中循环运行。

【问题讨论】:

    标签: c memory-management linked-list quicksort singly-linked-list


    【解决方案1】:

    这是错误的

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

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

    来分配
    char password[index+1];
    

    【讨论】:

    • 遗憾的是,即使这样,我仍在循环播放。
    • 是的,但是您需要先修复此类错误,以便有人能够找到您的错误。你试过调试器吗?
    【解决方案2】:

    函数read_data至少有三个严重的bug。

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

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

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

    在此声明中

    le->password = password;
    

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

    所以程序在任何情况下都有未定义的行为。

    函数free_list

    void free_list(list* mylist)
    {
    
        free(mylist->first);
        free(mylist);
    }
    

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

    您的列表设计也存在逻辑错误。如果你有一个双向链表,那么函数insert_list 应该将一个新节点附加到列表的尾部。否则单链表的尾节点就没有意义了。

    【讨论】:

    • 所以在我的理解中,free_list 应该是这样的:``` void free_list(list* mylist) { list_element* tmp = mylist->first; while(tmp->next != NULL) { free(mylist->first->password);免费(mylist->first); tmp = tmp->下一个; } 免费(我的列表); } ```
    • 密码语句如下: le->password = malloc(sizeof(char) * (strlen(password)+1)); strncpy(le->密码,密码,(strlen(密码)+1));
    【解决方案3】:

    这里有个问题。仔细看看你的 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 中获取“下一个”指针。除了 tmp 指向的东西现在已经消失了,因为你刚刚释放了它。

    【讨论】:

    • 其实你没有修复它。你需要设置 tmp = tmp->next before 你做释放。
    猜你喜欢
    • 1970-01-01
    • 2016-10-18
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多