[英]Why is there a Segmentation fault from trying to add to count and printf?
#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;
}
}
/* -------------------- */
將指針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()
之前,您也無法在任何地方初始化num
。 您應該類似地修復它。
您可能會考慮使用調試器,例如valgrind
。 分段錯誤並不總是發生在導致它的同一行代碼中(如果根本發生的話),並且作為錯誤檢查的一種方式可能不可靠。
PS使用if (Empty(que))
代替if (Empty(que) != 1)
足夠了,因為表達式在計算為非零整數時為“ true”。 可以說這是更安全的,因為所有“真實”值都不必為1
。
PPS不要#include
.c
文件。 包括.h
文件,並在主程序中編譯.c
文件。 如果您使用的是gcc
,那么
gcc myprogram.c QueueImplementation.c
其他編譯器使用相同的語法(某處可能有例外,但我沒有遇到過)。
在C語言中,只要聲明一個指針Queue *
,它就不會神奇地指向Queue *
的新“有效”實例。 實際上,它指向內存中的隨機位置,其中很可能不包含對您有意義的任何內容。
為簡化起見,在您的代碼中您正在執行以下操作:
因此,您正在將{NULL,NULL}寫入系統內存的隨機部分。
這不是您的操作方式。 查看Luddite提供的示例。
另外,請閱讀本文以了解此處發生的情況:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.