[英]Linked List value changes in gdb
我有一個C鏈表,看起來像這樣:
typedef struct Node {
struct Node *child;
void *value;
} Node;
typedef struct LinkedList {
Node *head;
} LinkedList;
為了測試一切是否正常,我有一個主程序,該程序逐行讀取文件,並將每一行存儲在以下Node中。 然后,一旦文件到達末尾,我將遍歷鏈接列表並打印所有行。
但是,當我對其進行測試時,它僅打印空白行,但文件中的最后一行除外,該行可以正常打印。 另外,盡管所有字符串在存儲在節點中之前都已進行了malloc分配,但是我得到了“指針未分配未分配錯誤”的信息。 我已經在gdb中進行了相當廣泛的研究,似乎無法弄清楚我做錯了什么。 也許其他人可以在這里幫助我? 這是我其余的代碼:
int main(int argc, char **argv) {
if (argc>1) {
FILE *mfile = fopen(argv[1], "r");
if (mfile!=NULL) {
char c;
char *s = (char*) malloc(1);
s[0] = '\0';
LinkedList *lines = (LinkedList*) malloc(sizeof(LinkedList));
while ((c=fgetc(mfile))!=EOF) {
if (c=='\n') {
setNextLine(lines, s);
free(s);
s = (char*) malloc(1);
s[0] = '\0';
}
else s = append(s, c);
}
if (strlen(s)>0) {
setNextLine(lines, s);
free(s);
}
fclose(mfile);
printList(lines);
LLfree(lines);
} else perror("Invalid filepath specified");
} else perror("No input file specified");
return 0;
}
void setNextLine(LinkedList *lines, char *line) {
struct Node **root = &(lines->head);
while (*root!=NULL) root = &((*root)->child);
*root = (Node*) malloc(sizeof(Node));
(*root)->child = NULL;
(*root)->value = line;
}
char *append(char *s, char c) {
int nl = strlen(s)+2;
char *retval = (char*) malloc(nl);
strcpy(retval, s);
retval[nl-2] = c;
retval[nl-1] = '\0';
free(s);
return retval;
}
void printList(LinkedList *lines) {
Node *root = lines->head;
while (root!=NULL) {
char *s = (char*) root->value;
printf("%s \n", s);
root = root->child;
}
}
void LLfree(LinkedList *list) {
if (list->head!=NULL) NodeFree(list->head);
free(list);
return;
}
void NodeFree(Node *head) {
if (head->child!=NULL) NodeFree(head->child);
free(head->value);
free(head);
return;
}
似乎在代碼中有幾件事可以更改。 也許最有幫助的一個可能是內存釋放不當。
更改:
setNextLine(lines, s);
free(s);
s = (char*) malloc(1);
至:
setNextLine(lines, s);
// free(s);
s = (char*) malloc(1);
指針“ s”仍指向剛剛分配給前一個節點的“值”的對象。 因此,調用“ free”實際上是在釋放節點的“值”。
試試這個
void NodeFree(Node *head)
if (head->child!=NULL)
NodeFree(head->child);
free(head->value);
free(head->child);
free(head);
head->value = NULL;
head->child = NULL;
head = NULL;
return;
}
setNextLine()
函數將's'poitner附加到節點值,然后在while循環中調用該指針后將釋放該指針。
這就是為什么當NodeFree()
嘗試釋放head->value
時會出現雙重釋放錯誤的原因。 而且,您得到最后一行的事實可能僅僅是因為's'指向最后一行的地址(它像前面的所有行一樣被釋放)仍未使用,盡管它不再分配給您的指針了。
您應該在setNextLine()
復制由“ s”指向的行,以便可以對其余行使用“ s”指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.