我在链表、堆栈和队列中经常收到这些错误。如果有人能指出我一次又一次犯的错误,那就太好了。
这是我编写的代码。
#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()
从列表末尾删除元素- 全局
front
是NULL
(空列表(或指向列表的第一个元素 - 全局
rear
要么NULL
(空列表(要么指向列表的最后一个元素 - 当列表为空时,
front == NULL
并rear == 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
...