[英]Segmentation fault with strcmp in a list insertion
我正在嘗試按字母順序創建一個列表(首先按作者,然后按名稱)。 我試圖通過將兩個字符串與strcmp()
進行比較來做到這一點,但我遇到了分段錯誤。
我將把 GDB 運行結果放在這里,而 function 是我用列表制作的第一個程序之一,因此代碼可能還有其他錯誤。
GDB 運行:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400c65 in insert (lPtr=0x7fffffffeb38, isbn_i=978044,
name_i=0x7fffffffeb40 "Suzanne Collins",
author_i=0x7fffffffeb80 "The Hunger Games") at main.c:178
178 while(strcmp(author_i, currPtr->author) < 0){
typedef struct library{ //struct insertion from stdin
int isbn;
char *author;
char *name;
int act; //actual books in memory
int tot; //total books
struct library *nextPtr; //node
}Lib;
typedef Lib *NodePtr;
//called by a while, receives input from integers and two arrays of char
void insert(NodePtr *lPtr, int isbn_i, char *name_i, char *author_i){
NodePtr newPtr = malloc(sizeof(Lib));
newPtr->isbn = isbn_i; //scanf insertion in node
newPtr->author = author_i;
newPtr->name = name_i;
newPtr->nextPtr = NULL;
NodePtr prevPtr = NULL;
newPtr->act = 1;
newPtr->tot = 1;
if(lPtr == NULL){ //empty list
*lPtr = newPtr;
return;
}
NodePtr currPtr = *lPtr;
while(strcmp(author_i, currPtr->author) < 0){ //author is different, list slides
prevPtr = currPtr;
currPtr = currPtr->nextPtr;
}
if(strcmp(author_i, currPtr->author)== 0){ //same author
while(strcmp(name_i, currPtr->name) < 0){ //list sliding
prevPtr = currPtr;
currPtr = currPtr->nextPtr;
}
if(strcmp(name_i, currPtr->name) == 0){
currPtr->act += 1; //updates current counter and returns (to avoid duplicates)
currPtr->tot += 1;
free(newPtr);
return;
}
}
prevPtr->nextPtr = newPtr; //insertion between two nodes
newPtr->nextPtr = currPtr;
}
在以下代碼中:
while(strcmp(author_i, currPtr->author) < 0){ //author is different, list slides
prevPtr = currPtr;
currPtr = currPtr->nextPtr;
}
您不檢查currPtr->nextPtr
是否為NULL
(在列表末尾),
如果您的列表作者僅包含應在author_i
之后排序的作者,您將到達末尾而找不到插入位置。
示例(為簡單起見,省略了無關字段):
currPtr = {author:"Cressida Cowell", nextPtr=NULL};
insert(lPtr = &currPtr, ...,author_i = "Suzanne Collins", ...);
/// insertion location loop
// while loop unrolled
if("Suzanne Collins" > "Cressida Cowell") {
prevPtr = currPtr ; // prevPtr = {author:"Cressida Cowell", nextPtr=NULL};
currPtr = currPtr->nextPtr; // currPtr = NULL
}
// next iteration
if("Suzanne Collins"> NULL->author ) // de-referencing a NULL pointer, causing a Segmentation fault
您可以通過以下修復部分修復代碼:
while(strcmp(author_i, currPtr->author) < 0){ //author is different, list slides
prevPtr = currPtr;
currPtr = currPtr->nextPtr;
if(currPtr == NULL) {break;} // exit loop if at end of the list
}
您仍然需要處理currPtr == NULL
以避免在檢查標題時取消引用 currPtr 中的currPtr
指針,我的建議是結合插入位置搜索循環中的條件。
// implement a node comparison function
int compareLib(NodePtr lib1, NodePtr lib2) {
if((lib1 == NULL)||(lib2 == NULL)) return 0;
int author_compare = strcmp(lib1->author, lib2->author);
if (author_compare != 0) return author_compare;
return strcmp(lib1->name, lib2->name);
}
...
while(compareLib(newPtr, currPtr)){
prevPtr = currPtr;
currPtr = currPtr->nextPtr;
if(currPtr == NULL) {break;} // exit loop if at end of the list
}
添加新列表節點時,您仍然需要處理currPtr == NULL
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.