如何在 Ubuntu 中使用代码::块解决 C 中的分段错误(核心转储)错误?



我正在使用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 个元素时会发生什么。在这种情况下,frontrear是相同的。进一步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);
}

其他注意事项:

您的代码使用全局变量frontrear。一般来说,我建议你不要使用全局变量。这令人困惑且容易出错。相反,您可以在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;
}
...

相关内容

  • 没有找到相关文章

最新更新