#include <stdio.h> /* the "QueueTypes.h" file, */
#include <stdlib.h> /* given above on lines 1:15, is */
#include "QueueImplementation.c"
void main(void){
Queue *que;
ItemType *num;
num = 0;
InitializeQueue(que);
int count = 0;
int check;
int i;
if(Empty(que) != 1){
count = count + 1;
}
printf("%d", count); <- segmentation fault
if(Remove(que, num) != 0){
count = count + 1; <- segmentation fault
}
这些是程序中不断出现分段错误的部分。我是非法访问任何东西吗?
这是queueimplementation.c。当我删除被指出的行时,程序正常工作并正常返回错误。
/* ------------< begin file "QueueImplementation.c" >------------ */
#include <stdio.h> /* the "QueueTypes.h" file, */
#include <stdlib.h> /* given above on lines 1:15, is */
#include "QueueInterface.h" /* included in "QueueInterface.h" */
/* on line 3 of Program 7.4. */
void SystemError(char *errorMsg) {fprintf(stderr,errorMsg);}
void InitializeQueue(Queue *Q)
{
Q->Front = NULL;
Q->Rear = NULL;
}
/* -------------------- */
int Empty(Queue *Q)
{
return (Q->Front == NULL);
}
/* -------------------- */
int Full(Queue *Q)
{ /* we assume an already constructed queue, Q, is */
return 0; /* not full, since it could potentially grow */
} /* as a linked structure */
/* -------------------- */
int Insert(ItemType R, Queue *Q)
{
QueueNode *Temp;
/* attempt to allocate */
Temp = (QueueNode *) malloc(sizeof(QueueNode)); /* a new node */
if (Temp == NULL) { /* Temp = NULL signals allocation */
SystemError("system storage is exhausted"); /* failure */
return 0;
} else {
Temp->Item = R;
Temp->Link = NULL;
if ( Q->Rear == NULL ) {
Q->Front = Temp;
Q->Rear = Temp;
} else {
Q->Rear->Link = Temp;
Q->Rear = Temp;
}
}
return 1;
}
/* -------------------- */
int Remove(Queue *Q, ItemType *F)
{
QueueNode *Temp;
if (Q->Front == NULL) {
SystemError("attempt to remove item from empty Queue");
return 0 ;
} else {
*F = Q->Front->Item;
Temp = Q->Front;
Q->Front = Temp->Link;
free(Temp);
if (Q->Front == NULL) Q->Rear = NULL;
return 1;
}
}
/* -------------------- */
答案 0 :(得分:2)
当您将指针que
传递给InitializeQueue()
时,尚未初始化指针{。}}。
更好的实现可能是将指针传递给指针que
(即Queue**
)到InitializeQueue()
void InitializeQueue(Queue **Q)
{
*Q = malloc(sizeof**Q); // set aside memory for your queue
Q->Front = NULL;
Q->Rear = NULL;
}
并像这样称呼它
Queue *que;
InitializeQueue(&que);
如果您无法更改QueueImplementation.c
的实现,请在函数调用之前调用malloc
,如下所示:
Queue *que = malloc(sizeof*que);
InitializeQueue(que);
或根本不使用堆分配(我的建议):
Queue que; // note that this is not a pointer
InitializeQueue(&que); // we have to take the address of it
请注意,使用上述选项,que
只能在定义它的函数内合法访问。但是,这应该不会影响您,因为您在main
中定义它,因此它将在您的程序的生命周期中存在。
对于两个malloc
选项,请务必在使用完毕后致电free()
。
在将num
传递给Remove()
之前,您也无法初始化valgrind
。你应该同样修复它。
您可以考虑使用if (Empty(que))
之类的调试器。分段错误并不总是在导致它的同一行代码中发生(如果它们发生),并且作为一种错误检查方式可能不可靠。
P.S。使用if (Empty(que) != 1)
而不是1
就足够了,因为当它们求值为非零整数时,表达式为“true”。它可以说更安全,因为所有“真实”值都不一定是#include
。
P.P.S。不要.c
.h
个文件。包含.c
文件并使用主程序编译gcc
文件。如果您使用的是gcc myprogram.c QueueImplementation.c
,那么
<input type="button" value="Test Fire!" onclick="debugger;" />
其他编译器使用相同的语法(某处可能存在异常,但我没有遇到过)。
答案 1 :(得分:1)
在C中,当你只是声明一个指针Queue *
时,它并没有神奇地指向一个新的&#34;有效的&#34;队列的实例。实际上,它指向内存中的随机位置,它很可能不包含对您有意义的任何内容。
为简化起见,在您的代码中:
因此,您正在将{NULL,NULL}写入系统内存的随机部分。
这不是你怎么做的。看看Luddite提供的例子。
另外,请阅读这篇文章以了解这里发生了什么: