我正在使用Code::Blocks IDE在C中运行链接队列数据结构。 下面是我的代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct LinkedQueue
{
int data;
struct LinkedQueue *next;
}Q;
Q *front , *rear;
int QEmpty( Q * );
void QInsert();
Q *QDelete();
void QDisplay( Q* );
int main()
{
int ans, choice;
front = NULL;
rear = NULL;
do
{
printf("n::Linked Queue Menu::");
printf("n 1. Insert ");
printf("n 2. Delete ");
printf("n 3. Display ");
printf("n 4. Exit ");
printf("n Enter your choice:");
scanf("%d", &choice);
switch( choice )
{
case 1: QInsert();
break;
case 2: front = QDelete();
break;
case 3: QDisplay(front);
break;
case 4: exit(0);
}
printf("nDo you want to go to main menu? (1/0) :");
scanf("%d", &ans);
}while ( ans == 1 );
return 0;
}
void QInsert()
{
Q *temp;
temp = (Q*)malloc(sizeof(Q));
temp->next = NULL;
if( temp == NULL)
{
printf("nMemory cannot be allocated");
return;
}
printf("nEnter the data:");
scanf("%d", &temp->data);
if( QEmpty( front ) )
{
front = temp;
rear = temp;
}
else
{
rear->next = temp;
rear = rear->next;
}
printf("nInsertion Successful");
}
int QEmpty( Q *front )
{
if( front == NULL )
return 1;
else
return 0;
}
Q *QDelete()
{
Q *temp;
temp = front;
if( QEmpty( front ) )
{
printf("nQueue Underflow!!");
printf("nReturning to main menu . . ");
return NULL;
}
else
{
printf("nThe deleted element is %d.", temp->data);
front = front->next;
temp->next = NULL;
free( temp );
}
return front;
}
void QDisplay( Q *front )
{
if( QEmpty( front ) )
{
printf("nThe Queue is empty");
}
printf("nThe display of Queue is:n");
printf("!!!->");
do
{
printf("%d", front->data);
front = front->next;
}while( front != rear );
}
当我运行这个程序时,插入和删除功能工作正常。但是当我调用显示函数时,它导致了分段错误(核心转储(。
请帮助我如何解决此错误。 提前谢谢。
@evolvedmicrobe的答案显示了QDisplay
中的错误,以防您的列表为空(即当front
为 NULL 时(。
这个答案将集中在QDisplay
中的另一个错误。
考虑当列表正好包含 1 个元素时会发生什么。在这种情况下,front
和rear
是相同的。进一步front->next
为空。
所以看看我按顺序 1(、2(、3( 和 4( 的评论(:
void QDisplay( Q *front )
{
if( QEmpty( front ) )
{
printf("nThe Queue is empty");
}
printf("nThe display of Queue is:n");
printf("!!!->");
do
{
printf("%d", front->data); // 1) In first loop this will print the data from the first element (fine)
// 4) In the second loop you deference front which is NULL => seg fault
front = front->next; // 2) Now front gets the value NULL
}while( front != rear ); // 3) Front and rear differs so the loop continuees
}
(注意:除了在正好有 1 个元素时导致错误外,您的方法也不利于"超过 1 个元素",因为您永远不会打印最后一个元素(
更好的方法是:
void QDisplay( Q *front )
{
if( QEmpty( front ) )
{
printf("nThe Queue is empty");
return;
}
printf("nThe display of Queue is:n");
printf("!!!->");
do
{
printf("%d", front->data);
front = front->next;
}while( front != NULL ); // or just } while(front);
}
其他注意事项:
您的代码使用全局变量front
和rear
。一般来说,我建议你不要使用全局变量。这令人困惑且容易出错。相反,您可以在main
中定义它们,并将指向它们的指针传递给需要更改它们的函数。或者 - 也许更好 - 将它们放在结构中,以便您可以将指针传递给该结构的变量(在main
中定义(。
如果你真的,真的,真的认为你需要全局变量,我强烈建议你永远不要对局部变量和函数参数使用相同的名称。换句话说:您当前QDisplay
有一个名为front
的参数 - 就像全局变量front
一样。这有点令人困惑...当您在QDisplay
内部分配某些东西以front
时会发生什么?全球front
会改变吗?答案是否定的,但为了避免混淆,最好为函数参数使用另一个名称。喜欢:
void QDisplay( Q *p )
{
if( QEmpty( p ) )
{
printf("nThe Queue is empty");
return;
}
printf("nThe display of Queue is:n");
printf("!!!->");
do
{
printf("%d", p->data);
p = p->next;
}while( p != NULL ); // or just } while(p);
}
在你的函数QDisplay
中,你检查指针是否为空,但如果该条件为真,则不要退出,而是继续取消引用指针,这将导致段错误。 您需要修改方法以在队列为空时返回。 例如
void QDisplay( Q *front )
{
if( QEmpty( front ) )
{
printf("nThe Queue is empty");
// Two lines below added by me
printf("nReturning to main menu . . ");
return;
}
...