如何修复链表分段错误 C
How to fix linked-list Segmentation fault C
我正在尝试通过以下代码解决 'segmentation-fault' 的问题,
我可能认为我没有了解全貌,这就是为什么我不断获得分段错误而不是分段错误的原因,
任何有助于深入理解这一点的帮助,都会鼓励我进行自我分析。
代码应该很简单:给定两个列表,我想从第一个列表中删除第二个列表中出现的所有元素,
我的努力是:
typedef struct EL {
int info;
struct EL *next;
} ElementoLista;
typedef ElementoLista *ListaDiElementi;
void filterLists(ListaDiElementi *lista1,ListaDiElementi *lista2) {
ListaDiElementi aux = *lista1,aus = *lista2,corr;
while(aux != NULL) {
if(aux->info == aus->info) { // Erase from the first
corr = aux;
aux = aux->next;
free(corr);
}
else {
if(aus != NULL) //Increase the second
aus = aus->next;
else {
aus = *lista2; //Restart
aux = aux->next;
}
}
}
}
我想两个列表中元素的顺序无关,解决方案可以是:
#include <stdlib.h>
#include <stdio.h>
typedef struct EL {
int info;
struct EL *next;
} ElementoLista;
ElementoLista * make(int i, ElementoLista * n)
{
ElementoLista * r = malloc(sizeof(ElementoLista));
if (r == NULL) {
/* change that code with what you want */
puts("out of memory");
exit(-1);
}
r->info = i;
r->next = n;
return r;
}
/* I suppose nothing about the order of the element in the two lists */
void filterLists(ElementoLista ** plista1, ElementoLista * lista2) {
/* have to work on plista1, not on a var valuing *plista1,
to be able to update it when a cell is removed */
while (*plista1 != NULL) {
ElementoLista * p;
/* is the info present in the second list ? */
for (p = lista2; p != NULL; p = p->next) {
if ((*plista1)->info == p->info) {
/* remove the cell */
ElementoLista * rmv = *plista1;
*plista1 = (*plista1)->next;
free(rmv);
break;
}
}
if (p == NULL)
/* the current cell was not removed, go to the next */
plista1 = &(*plista1)->next;
}
}
void pr(ElementoLista * l)
{
putchar('{');
while (l != NULL) {
printf(" %d", l->info);
l = l->next;
}
puts(" }");
}
int main()
{
ElementoLista * l1 = make(1, make(2, make(3, make(4, 0))));
ElementoLista * l2 = make(3, make(1, 0));
pr(l1);
filterLists(&l1, l2);
pr(l1);
return 0;
}
我删除了你的 typedef 隐藏指针,这样做是个坏主意,因为这会扰乱 reader
如你所见,给出第二个列表的指针地址是没有用的,因为那个没有被修改
执行:
{ 1 2 3 4 }
{ 2 4 }
您的代码有几个问题:
当第二个列表比另一个短时,你会得到一个段错误,因为你没有在第一个 if 语句中检查 aus
是否为 NULL。
如果删除了第一个列表中间的元素,您稍后会遇到另一个段错误,因为已删除元素的前身仍指向原始元素,但已释放内存。
我不知道这是否是个问题,但您的算法似乎只适用于排序列表,请查看这两个列表,例如 [1,2] 和 [2, 1].
为了帮助您使用算法,我们需要知道您喜欢如何处理重复元素以及列表是否已排序。
我正在尝试通过以下代码解决 'segmentation-fault' 的问题, 我可能认为我没有了解全貌,这就是为什么我不断获得分段错误而不是分段错误的原因, 任何有助于深入理解这一点的帮助,都会鼓励我进行自我分析。
代码应该很简单:给定两个列表,我想从第一个列表中删除第二个列表中出现的所有元素, 我的努力是:
typedef struct EL {
int info;
struct EL *next;
} ElementoLista;
typedef ElementoLista *ListaDiElementi;
void filterLists(ListaDiElementi *lista1,ListaDiElementi *lista2) {
ListaDiElementi aux = *lista1,aus = *lista2,corr;
while(aux != NULL) {
if(aux->info == aus->info) { // Erase from the first
corr = aux;
aux = aux->next;
free(corr);
}
else {
if(aus != NULL) //Increase the second
aus = aus->next;
else {
aus = *lista2; //Restart
aux = aux->next;
}
}
}
}
我想两个列表中元素的顺序无关,解决方案可以是:
#include <stdlib.h>
#include <stdio.h>
typedef struct EL {
int info;
struct EL *next;
} ElementoLista;
ElementoLista * make(int i, ElementoLista * n)
{
ElementoLista * r = malloc(sizeof(ElementoLista));
if (r == NULL) {
/* change that code with what you want */
puts("out of memory");
exit(-1);
}
r->info = i;
r->next = n;
return r;
}
/* I suppose nothing about the order of the element in the two lists */
void filterLists(ElementoLista ** plista1, ElementoLista * lista2) {
/* have to work on plista1, not on a var valuing *plista1,
to be able to update it when a cell is removed */
while (*plista1 != NULL) {
ElementoLista * p;
/* is the info present in the second list ? */
for (p = lista2; p != NULL; p = p->next) {
if ((*plista1)->info == p->info) {
/* remove the cell */
ElementoLista * rmv = *plista1;
*plista1 = (*plista1)->next;
free(rmv);
break;
}
}
if (p == NULL)
/* the current cell was not removed, go to the next */
plista1 = &(*plista1)->next;
}
}
void pr(ElementoLista * l)
{
putchar('{');
while (l != NULL) {
printf(" %d", l->info);
l = l->next;
}
puts(" }");
}
int main()
{
ElementoLista * l1 = make(1, make(2, make(3, make(4, 0))));
ElementoLista * l2 = make(3, make(1, 0));
pr(l1);
filterLists(&l1, l2);
pr(l1);
return 0;
}
我删除了你的 typedef 隐藏指针,这样做是个坏主意,因为这会扰乱 reader
如你所见,给出第二个列表的指针地址是没有用的,因为那个没有被修改
执行:
{ 1 2 3 4 }
{ 2 4 }
您的代码有几个问题:
当第二个列表比另一个短时,你会得到一个段错误,因为你没有在第一个 if 语句中检查
aus
是否为 NULL。如果删除了第一个列表中间的元素,您稍后会遇到另一个段错误,因为已删除元素的前身仍指向原始元素,但已释放内存。
我不知道这是否是个问题,但您的算法似乎只适用于排序列表,请查看这两个列表,例如 [1,2] 和 [2, 1].
为了帮助您使用算法,我们需要知道您喜欢如何处理重复元素以及列表是否已排序。