分段错误,在 C 中列出



我尝试使用两个函数直接对我在链表中输入的数字进行排序,第一个函数在头部添加元素,第二个包含分割错误,应该利用第一个函数来完成这项工作。

#include <stdio.h>
#include <stdlib.h>
typedef struct cellule
{
    int val;
    struct cellule *suivant;
} cellule;
typedef struct cellule* liste;
liste insert_tete(liste L,int n)
{
    liste p;
    p=malloc(sizeof(cellule));
    p->val=n;
    p->suivant=L;
    return p;
}//ok :)
liste insert_croissant(liste L,int n)
{
    if(!L)
    {
        L=insert_tete(L,n);
        return L;
    }
    liste p,q;
    for(q=L,p=L; (p!=NULL )&&(n> (p->val)) ; q=p,p=p->suivant); //
    p=insert_tete(p,n);
    q->suivant=p;
    return L;
}

我绝不相信这会修复它,但您的代码中至少有一个错误。

考虑初始化 L

的情况,但 n val:

// p = L, q = L;
// Let L = [val|->...
p=insert_tete(p,n);
// p = [n|->[val|->...
q->suivant=p;
// q = L
// Therefore [val|->[n|->L
// And you've just made your linked list circular.
liste insert_croissant(liste L,int n)
{
    if(!L)
    {
        L=insert_tete(L,n);
        return L;
    }

在这里我们知道L不是NULL

    liste p,q;
    for(q=L,p=L; (p!=NULL )&&(n> (p->val)) ; q=p,p=p->suivant); //

在这里获得合法段错误的唯一方法是p遵循的指针之一是非 0 指针,它不指向正确分配的struct cellule,而是指向一些无法访问的内存。然后尝试访问p->val(或p->suivant)会导致段错误。

进入这种情况的最常见方法(根据我有限的经验)是忘记将第一个指针初始化为 0。

代码存在一个问题,即列表在某些情况下可能会损坏;很容易使列表进入未正确终止的状态(并且可能从列表中"丢失"节点)。 这种情况可能会导致问题,具体取决于其他代码可能如何操作列表。

如果您尝试在不为空的列表中添加新节点,但新值小于或等于第一个节点的值,则该列表最终将成为包含两个节点的循环列表。位于列表顶部的节点之后的任何节点都将丢失。

发生这种情况是因为在这种情况下,调用insert_tete(p,n)时,pq 都将指向该节点。insert_tete(p,n)返回后,p-suivantq 将指向列表开头的节点。 所以当

q->suivant = p;

被执行,列表将是循环的,"额外"节点将丢失。

根据其他操作在列表上的操作方式(特别是删除元素时/方式),您可能会发现自己在suivant字段中留下了一个悬空指针(这可能会导致段错误),或者最终进入无限循环。

使用指针到指针的简化版本。注意:空列表没有特殊情况。

struct cellule {
    int val;
    struct cellule *suivant;
    };
struct cellule *insert_croissant(struct cellule **LL, int val)
{
    struct cellule *p,**pp;
    for(pp=LL  ; *pp && (*pp)->val < val ; pp = &(*pp)->suivant) {;}
      /* When we arrive here, pp points to whatever pointer happens
      ** to point to our current node.
      ** - If the list was empty, *pp==NULL
      ** - if the place to insert happens to be the tail of the list, *p is also NULL        
      ** - in all cases, *pp should be placed after the new node, and the new node's pointer should be assigned to *pp
      */
    p = malloc(sizeof *p);
    p->val = val;
    p->suivant = *pp;
    *pp = p;
    return *LL;
}

相关内容

  • 没有找到相关文章

最新更新