首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gdb中的链接列表值更改

gdb中的链接列表值更改
EN

Stack Overflow用户
提问于 2014-05-15 13:59:18
回答 3查看 197关注 0票数 0

我有一个C链表,看起来像这样:

代码语言:javascript
复制
typedef struct Node {
    struct Node *child;
    void *value;
} Node;

typedef struct LinkedList {
    Node *head;
} LinkedList;

为了测试一切是否正常工作,我有一个主程序,它逐行读取文件,并将每一行存储在下面的Node中。然后,一旦文件到达末尾,我将遍历链表并打印所有行。

但是,当我测试它时,它只打印空行,除了文件中的最后一行,它可以正常打印。此外,尽管所有字符串在存储到节点之前都是错误锁定的,但我得到了一个“指针空闲时未分配错误”。我在gdb中经历了相当广泛的这一过程,似乎找不出我做错了什么。也许其他人能帮我一下?下面是我剩下的代码:

代码语言:javascript
复制
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;
}
EN

回答 3

Stack Overflow用户

发布于 2014-05-15 14:26:53

看起来代码中有几个地方是可以修改的。也许最有可能有帮助的是内存被不适当地释放。

更改:

代码语言:javascript
复制
                setNextLine(lines, s);
                free(s);
                s = (char*) malloc(1);

至:

代码语言:javascript
复制
                setNextLine(lines, s);
//              free(s);
                s = (char*) malloc(1);

指针“%s”仍然指向刚刚分配给上一个节点的“value”的内容。因此,调用'free(s)‘实际上是释放节点的'value’。

票数 1
EN

Stack Overflow用户

发布于 2014-05-15 16:08:00

试着这样做

代码语言:javascript
复制
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;
}
票数 0
EN

Stack Overflow用户

发布于 2014-05-15 18:12:07

setNextLine()函数将's‘poitner附加到节点值,然后在while循环中的那个调用之后释放相同的指针。

这就是为什么当NodeFree()试图释放head->value时,你会得到一个双重的释放错误。而你得到最后一行的原因可能只是因为's‘指向最后一行的地址(就像之前的所有行一样被释放了),尽管它不再被分配给你的指针,但它仍然没有被使用。

您应该在setNextLine()中复制由's‘指向的行,以便您可以在其余行中使用's’指针。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23670349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档