这是我的链表结构:
typedef struct intervalo *Lista;
typedef struct intervalo
{
int num;
Lista next;
}Lista_int;
这是我的代码(我制作)中破坏列表的部分:
Lista destroi_lista_res(Lista lista)
{
Lista temp_ptr;
while (lista->next!= NULL)
{
temp_ptr = lista;
lista= lista->next;
free(temp_ptr);
}
free(lista);
return NULL;
}
不幸的是,当调用此函数时,我的程序会挂起。具体来说,while (lista->next!= NULL)
永远不会终止。
我的问题:为什么这一行导致无限循环?
其他代码详情:
在main()中,创建了两个列表。
/* Create linked list. */
Lista cria_lista_cab()
{
Lista aux;
aux=(Lista)malloc(sizeof(Lista_int));
if(aux!=NULL)
{
aux->next=NULL;
}
return aux;
}
以下函数用于将数字节点添加到两个列表的末尾:
/* Insert node at the list tail. */
void insere_elem(Lista *lista,int num)
{
Lista aux,ant_pos=*lista,pos=ant_pos->next;
aux=(Lista)malloc(sizeof(Lista_int));
while(pos!=NULL)
{
ant_pos=ant_pos->next;
pos=pos->next;
}
aux->num=num;
aux->next=pos;
ant_pos->next=aux;
}
下一个函数组合了两个列表的数字节点,消除了重复数字增加的数字。返回结果列表:
Lista cria_lista_una(Lista lista1,Lista lista2)
{
Lista lista_res=cria_lista_cab();
lista1=lista1->next;
lista2=lista2->next;
while(lista1!=NULL && lista2!=NULL)
{
if(lista1->num<lista2->num)
{
insere_elem(&lista_res,lista1->num);
printf("\n1 %d %d",lista1->num,lista2->num);
if(lista1!=NULL)
lista1=lista1->next;
}
else if(lista2->num<lista1->num)
{
insere_elem(&lista_res,lista2->num);
printf("\n2 %d %d",lista1->num,lista2->num);
if(lista2!=NULL)
lista2=lista2->next;
}
else if(lista2->num==lista1->num)
{
printf("\n3 %d %d",lista1->num,lista2->num);
if(lista1!=NULL)
lista1=lista1->next;
else if(lista2!=NULL)
lista2=lista2->next;
}
}
if(lista1!=NULL)
{
while(lista1!=NULL)
{
insere_elem(&lista_res,lista1->num);
lista1=lista1->next;
}
}
else if(lista2!=NULL)
{
while(lista2!=NULL)
{
insere_elem(&lista_res,lista2->num);
lista2=lista2->next;
}
}
return lista_res;
}
以下功能用于打印列表。
void imprime_lista_res(Lista lista)
{
lista=lista->next;
while(lista!=NULL)
{
printf("\nNum-> %d",lista->num);
lista=lista->next;
}
}
除了在调用destroi_lista_res()并且程序挂起时清理时,所有内容似乎都按预期运行。
答案 0 :(得分:3)
这可能是因为lista
开头为NULL。
将功能更改为:
Lista destroi_lista_res(Lista lista)
{
Lista temp_ptr;
while (lista!= NULL)
{
temp_ptr = lista;
lista= lista->next;
free(temp_ptr);
}
return NULL;
}
答案 1 :(得分:0)
给出你的代码:
void insere_elem(Lista *lista,int num)
{
Lista aux,ant_pos=*lista,pos=ant_pos->next;
aux=(Lista)malloc(sizeof(Lista_int));
并记住Lista实际上被定义为a 指向struct Lista_int
的实例的指针您的代码变为: 注意:您实际将节点附加到链接列表,而不是插入
void insere_elem(struct Lista_int* *lista,int num) //note the ptr to ptr
{
struct Lista_int * aux;
struct Lista_int * ant_pos=*lista; //gets ptr to first instance of struct Lista_int
struct Lista_int * pos=ant_pos->next; // get ptr to NULL or second instance of..
// get ptr to new instance of struct
aux=(struct Lista_int*)malloc(sizeof(Lista_int));
// HERE should be checking that malloc() was successful
// otherwise, the lines:
// aux->num=num;
// aux->next=pos;
// will be writing to offsets from address 0
// will probably cause a crash
// step forward through linked list to find last struct
while(pos!=NULL)
{
ant_pos=ant_pos->next; // step ptr to prior struct
pos=pos->next; // step ptr to current struct
}
aux->num=num; // set fields in new struct
aux->next=pos; // pos is already NULL, so probably (for clarity) just use NULL
ant_pos->next=aux; // set old struct instance ptr to new instance of struct
}
另外,关于这段代码:
while(lista2!=NULL)
{
insere_elem(&lista_res,lista2->num);
lista2=lista2->next;
}
此循环从链接列表'lista_res'的头部开始 因此,对于当前链表中的每个元素,它都会添加另一个元素 一般来说, 这意味着链接列表的大小加倍,每个条目都会进入此代码序列
答案 2 :(得分:0)
在你的distroi函数中,如果Lista已经为NULL,它会做什么,那么它将通过分段错误。但是根据你的说法,如果你要退出该功能,那么你可能无法正确创建列表。 首先进行如下更改:
Lista destroi_lista_res(Lista lista)
{
Lista temp_ptr;
while (lista!= NULL)
{
temp_ptr = lista;
lista= lista->next;
free(temp_ptr);
}
return NULL;
}
需要注意的另一件事是&#34;您是否正确创建了列表,如果是,那么您的打印功能将无法正常工作。为了确保这一点,请为调试目的制作一个虚拟遍历函数,它只是跟你在distroi函数中一样遍历列表。