[英]Segmentation Fault in Mergesort implementation
我有一個程序 Mergesort 與一個無序列表一起工作。我得到的問題是 Segmentation Fault (core dumped)。
實際上,我經常收到此錯誤,但我不知道如何解決。 此外,它不會顯示任何錯誤或警告消息來查找它。 在這個源代碼和其他一般情況下,我真的需要知道為什么我有這個以及我如何修復它。
#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;
}
首先,在包含stdlib.h
調用您的函數mergesort
是不正確的,並且應該會在最近的 C 編譯器中引發錯誤。
接下來,此代碼序列通過取消引用空指針來調用未定義行為:
node *z = NULL;
node *c = z;
c->next = a; // UB!
此時, c為NULL,因此您不應使用c->next
。 使用常見的 C 實現嘗試寫入導致 seg 錯誤的不允許的內存。
您的算法嘗試使用sentinel ,但恕我直言,這不是一個合適的用例。 只記住第一個值更簡單。 並且您還應該處理到達兩個排序列表之一末尾的情況。 代碼可以變成:
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 語言中,您不需要強制轉換 malloc 。
即使使用我的修復,如果您不更改mergesort
函數的名稱,您的代碼也會在任何體面的C編譯器上mergesort
。 你被警告了。
對於最后一個問題,我認為分段錯誤的主要原因是訪問未初始化、超出程序范圍或嘗試修改字符串文字的內存。 這些可能會導致分段錯誤,但不能保證它們會導致分段錯誤。 以下是分段錯誤的一些常見原因 -
訪問數組越界
取消引用 NULL 指針
取消引用已釋放的內存
取消引用未初始化的指針
“&”(地址)和“*”(取消引用)運算符的錯誤使用
printf 和 scanf 語句中的格式說明符不正確
堆棧溢出
寫入只讀存儲器
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.