c语言 - 如何修复此代码中的'Segmentation fault (core dumped)'?



我在链表、堆栈和队列中经常收到这些错误。如果有人能指出我一次又一次犯的错误,那就太好了。

这是我编写的代码。

#include <stdio.h>
#include <malloc.h>
struct Node
{
int data;
struct Node* next;
}*front=NULL,*rear=NULL;
void enqueue(struct Node *front,struct Node *rear,int ele)
{
struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
struct Node* ptr=front;
if (temp==NULL)
printf("Overflow");
else
{
if (front==NULL)
{
temp->data=ele;
temp->next=NULL;
front=temp;
printf("%d",front->data);
}
else
{
printf("Srishti");
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
temp->next=front;
ptr->next=temp;
rear=temp;
}
}
}
void dequeue()
{
struct Node *temp=front;
if(front!=NULL && front->next!=NULL)
{
rear->next=front->next;
front=front->next;
}
}
void display()
{
struct Node *temp=front;
while(temp->next!=front)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("%d",rear->data);
}
void main()
{
int n,i;
for(i=0;i<3;i++)
{
printf("Enter Element");
scanf("%d",&n);
enqueue(front,rear,n);
}
display();
}

我看到的输出总是Segmentation Fault (core dumped).我尝试在多台机器和编译器上运行代码,但仍然没有区别。

通常避免使用同名的全局变量和参数,这有点令人困惑,可能会导致您看到的问题。

按照你的代码现在的情况,当你在函数中更改front时,你实际上不是在改变全局变量 front,而是一个副本。

因此,要么将前后地址传递到函数中,要么完全删除参数。

void enqueue(struct Node **front,struct Node **rear,int ele)
{
struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
struct Node* ptr=*front;
...
if (front == NULL)
{
temp->data = ele;
temp->next = NULL;
*front = temp;      // this will actually change front
printf ("%d", front->data);
}

并将其称为

int n, i;
for (i = 0; i < 3; i++)
{
printf ("Enter Element");
// scanf ("%d", &n); avoid using scanf like this, use instead fgets
char line[32];
if (fgets(line, sizeof(line), stdin) != NULL)
{ 
int n = atoi(line); 
enqueue (&front, &rear, n);
}
}  

以下代码无需引发分段错误即可工作。我对代码进行了一些小的更改。我想我在代码中的注释将解释对您的代码所做的更改。

#include <stdio.h>
#include <malloc.h>
struct Node
{
int data;
struct Node* next;
}*front=NULL,*rear=NULL;
//remove the local arguments
void enqueue(int ele)
{
struct Node *temp=(struct Node*)malloc(sizeof(struct Node));
struct Node* ptr=front;
if (temp==NULL)
printf("Overflow");
else
{
if (front==NULL)
{
temp->data=ele;
temp->next=NULL;
front=temp;
printf("%d",front->data);
}
else
{
printf("Srishti");
// check the breaking condition
while(ptr->next!=NULL && ptr->next != front)
{
ptr=ptr->next;
}
// putting the ele in the data space of Node
temp->data = ele;
temp->next=front;
ptr->next=temp;
rear=temp;
}
}
}
void dequeue()
{
struct Node *temp=front;
if(front!=NULL && front->next!=NULL)
{
rear->next=front->next;
front=front->next;
}
}
void display()
{
struct Node *temp=front;
while(temp->next!=front)
{
printf("%d",temp->data);
temp=temp->next;
}
printf("%d",rear->data);
}
void main()
{
int n,i;
for(i=0;i<3;i++)
{
printf("Enter Element");
scanf("%d",&n);
enqueue(n);
}
display();
}

首先要做的是:始终启用编译器错误和警告。编译器是你的朋友而不是你的敌人

从代码中不清楚您到底要实现什么。因此,对于我的解决方案,我假设您需要以下内容:

  • enqueue()将新元素添加到列表末尾
  • dequeue()从列表末尾删除元素
  • 全局frontNULL(空列表(或指向列表的第一个元素
  • 全局rear要么NULL(空列表(要么指向列表的最后一个元素
  • 当列表为空时,front == NULLrear == NULL
  • 如果列表有一个条目,则front == rear
  • 如果列表不为空,则rear->next == NULL

更新的代码:

#include <stdlib.h>
#include <stdio.h>
struct Node {
int data;
struct Node* next;
} *front = NULL, *rear = NULL;
void enqueue(int ele)
{
struct Node *temp = calloc(sizeof(struct Node), 1);
if (temp == NULL) {
printf("Overflow");
exit(1);
} else {
if (front == NULL) {
/* list is empty */
front = temp;
} else {
/* add to end of list */
rear->next = temp;
}
temp->data = ele;
rear       = temp;
}
}
void dequeue()
{
/* special cases: empty or only one element */
if (rear == front) {
if (front != NULL)
free(front);
front = rear = NULL;
return;
}
struct Node *temp = front;
while (temp->next != rear)
temp = temp->next;
rear = temp;
free(temp->next);
temp->next = NULL;
}
void display()
{
if (front == NULL)
return;
struct Node *temp = front;
while (temp) {
printf("%dn", temp->data);
temp = temp->next;
}
printf("n");
}
int main(void)
{
int n,i;
for (i=0; i<3; i++) {
printf("Enter Element ");
scanf("%d",&n);
enqueue(n);
}
/* show list & dequeue() functionality */
for (i=0; i<3; i++) {
display();
dequeue();
}
display();
/* show that dequeue() is safe on empty list */
dequeue();
return 0;
}

示例运行:

$ gcc -Wall -Werror -o dummy dummy.c
$ valgrind ./dummy
==9093== Memcheck, a memory error detector
...
Enter Element 1
Enter Element 2
Enter Element 3
1
2
3
1
2
1
==9093== 
==9093== HEAP SUMMARY:
==9093==     in use at exit: 0 bytes in 0 blocks
==9093==   total heap usage: 5 allocs, 5 frees, 2,096 bytes allocated
==9093== 
==9093== All heap blocks were freed -- no leaks are possible
...

相关内容

  • 没有找到相关文章

最新更新