Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Mergesort实现中的分段错误_C_Algorithm_Merge_Linked List_Coredump - Fatal编程技术网

C Mergesort实现中的分段错误

C Mergesort实现中的分段错误,c,algorithm,merge,linked-list,coredump,C,Algorithm,Merge,Linked List,Coredump,我有一个程序Mergesort,它可以处理无序的链表。我遇到的问题是分段错误(核心转储) 事实上,我经常遇到这个错误,但我不知道如何修复它。此外,它不会显示任何错误或警告消息来查找它。在这个源代码和其他一般情况下,我真的需要知道为什么我有这个,以及如何修复它 #include <stdio.h> #include <stdlib.h> typedef struct node_t node; typedef struct node_t { int key; node *n

我有一个程序Mergesort,它可以处理无序的链表。我遇到的问题是分段错误(核心转储)

事实上,我经常遇到这个错误,但我不知道如何修复它。此外,它不会显示任何错误或警告消息来查找它。在这个源代码和其他一般情况下,我真的需要知道为什么我有这个,以及如何修复它

#include <stdio.h>
#include <stdlib.h>

typedef struct node_t node;
typedef struct node_t { int key; node *next; } node;
static node *head, *z;
node *merge(node *a, node *b)
{
    z->next =z;
    node *c = z;
    do
    {
        if (a->key > b->key)
        {
            c->next = a; c = a; a = a->next;
        }
        else
        {
            c->next = b; c = b; b = b->next;
        }
    } while (c != z);
    c = z->next;
    z->next = NULL;
    return c;
}
node *mergesort(node *c) {
    node *a = NULL; 
    node *b = NULL;
    if (c != NULL && c->next->next != NULL) {
        a = c; b = c;
        while (b->next != NULL && b->next->next != NULL) {
            c = c->next;
            b = b->next->next;
        }
        b = c->next;
        c->next = NULL;
        return merge(mergesort(a), mergesort(b));
    }
    return c;
}
void printList(node* node) 
{ 
    while (node != NULL) { 
        printf("%d ", node->key); 
        node = node->next; 
    } 
} 
node *listcreate(int n, node *a)
{
    node *head = NULL;
    node *temp = NULL;
    node *p = NULL;
    int i=0;
    while(i<n)
    {
        temp = (node*) malloc(sizeof(node*));
        printf("Please insert the number: ");
        scanf("%d", &(temp->key));
        temp->next = NULL;
        if(head == NULL)
        head = temp;
        else
        {
            p = head;
            while(p->next != NULL)
            p = p->next;
            p->next = temp;
        }
        i++;
    }
    a = head;
}
int main() 
{ 
    node *a = NULL;
    listcreate(3, a);
    a = mergesort(a);
    printf("Sorted Linked List is: \n"); 
    printList(a); 

    getchar(); 
    return 0; 
} 
#包括
#包括
类型定义结构节点\u t节点;
typedef结构节点{int key;节点*next;}节点;
静态节点*head,*z;
节点*合并(节点*a、节点*b)
{
z->next=z;
节点*c=z;
做
{
如果(a->key>b->key)
{
c->next=a;c=a;a=a->next;
}
其他的
{
c->next=b;c=b;b=b->next;
}
}而(c!=z);
c=z->next;
z->next=NULL;
返回c;
}
节点*合并排序(节点*c){
node*a=NULL;
node*b=NULL;
如果(c!=NULL&&c->next->next!=NULL){
a=c;b=c;
而(b->next!=NULL&&b->next->next!=NULL){
c=c->next;
b=b->next->next;
}
b=c->next;
c->next=NULL;
返回merge(mergesort(a),mergesort(b));
}
返回c;
}
无效打印列表(节点*节点)
{ 
while(node!=NULL){
printf(“%d”,节点->键);
节点=节点->下一步;
} 
} 
节点*列表创建(int n,节点*a)
{
node*head=NULL;
节点*temp=NULL;
node*p=NULL;
int i=0;
while(ikey));
temp->next=NULL;
if(head==NULL)
压头=温度;
其他的
{
p=水头;
while(p->next!=NULL)
p=p->next;
p->next=温度;
}
i++;
}
a=头部;
}
int main()
{ 
node*a=NULL;
列表创建(3,a);
a=合并排序(a);
printf(“排序链表为:\n”);
印刷品清单(a);
getchar();
返回0;
} 

对于最后一个问题,我认为分段错误的主要原因是访问未初始化的内存、超出程序的范围或试图修改字符串文本。这些可能会导致分段故障,但不能保证它们会导致分段故障。下面是分段错误的一些常见原因−

访问数组超出范围

取消对空指针的引用

解除对已释放内存的引用

取消对未初始化指针的引用

不正确使用“&”(地址)和“*”(解引用)运算符

printf和scanf语句中的格式说明符不正确

堆栈溢出


写入只读内存

首先,在包含stdlib.h时调用函数mergesort是不正确的,应该会在最近的C编译器中引发错误

接下来,此代码序列通过取消引用空指针来调用未定义的行为:

node *z = NULL;
node *c = z;
c->next = a;  //  UB!
此时,cNULL,因此不能使用
c->next
。使用通用C实现尝试写入导致seg故障的不允许内存


您的算法尝试使用哨兵,但我认为这不是一个合适的用例。只记住第一个值更简单。您还应该处理到达两个排序列表之一末尾的情况。该守则可以变成:

node *merge(node *a, node *b)
{
    node *c = z;           // current node initialized to null
    node *top;             // declare the future return value
    do
    {
        if (a->key > b->key)
        {
            if (c == z) top = a;    // if first value, remember it
            else c->next = a;       // else add the node to current list
            c = a; a = a->next;
            if (a == NULL) {        // explicitely handle end of input list
                c->next = b;
                break;
            }
        }
        else
        {
            if (c == z) top = b;
            else c->next = b; 
            c = b; b = b->next;
            if (b == NULL) {
                c->next = a;
            break;
            }
        }
    } while (c != z);
    return top;
}
但这还不是全部。你的代码是C和C++的混合。您只使用C库函数,但用C++编译器编译代码。C语言不允许函数重载,因此不应使用其他参数集(
mergesort
)重复使用标准库的函数名。而在C语言中


即使使用我的修复,如果不更改
mergesort
函数的名称,您的代码也会在任何体面的C编译器上中断。您已收到警告。

您的
z
节点的用途是什么?“它不会显示任何错误或警告消息”-是的,它会显示。使用
-Wall-Wextra
编译。此外,
z
的目的是什么?这毫无意义。z是哨兵键,你可以在谷歌上搜索。你认为这是这个错误的原因吗?@HoangNam非常肯定,是的。如果这是您的sentinel,那么您可能希望将其初始化为除
NULL
@dragosht之外的其他内容。我需要如何更改它?实际上我仍然不知道为什么“mergesort while include stdlib.h”是错误的。stdlib在这里为我提供了malloc函数
stdlib.h
提供了
malloc
的声明。不幸的是,它还声明了
intmergesort(void*base,size\u t nmemb,size\u t size,int(*compar)(constvoid*,constvoid*)与您的冲突。我不提供您提到的参数。我提供了一个不同的version@HoangNam当前位置你可能听不进我们说的话,但在那种情况下,问问题是没有用的。我确切地说,stdlib.h的版本与您的版本冲突(这意味着声明的参数与您的不同)。这将是正确的C++,因为名称的限制,这允许一个函数用不同的参数集声明,但在C语言中是被禁止的。好的,因为我是C语言的新手,所以我不知道在STDLIB。但我认为这没什么大不了的,因为即使在这个库中,我也能够自己重新定义函数,而不会出现任何错误