簡體   English   中英

gdb中的鏈接列表值更改

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM