我正在无限循环中运行,我不知道为什么。我试图调试我的代码,但没有成功。也许有人可以帮我解决这个问题。
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:在注释的帮助下修复了代码。现在,我在分区函数中循环运行。
这是错误的
char password[index];
strncpy(password, line, index);
password[index] = '\0';
您分配了index
个字符,但是使用最后一个语句在数组外部覆盖。您应该使用
char password[index+1];
函数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
应该在列表的末尾附加一个新节点。否则,将尾节点用于单链列表没有太大意义。
这里有个问题。仔细看看您的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指向的东西现在不见了,因为您刚刚释放了它。