Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中双链表的分段错误_C_Linked List - Fatal编程技术网

C语言中双链表的分段错误

C语言中双链表的分段错误,c,linked-list,C,Linked List,这让我快发疯了。当我在这个双链接列表上运行测试程序时,当我尝试释放列表时,它会给我一个分段错误。我知道由于没有正确释放分配的内存而导致内存泄漏,但无论我做什么尝试,它似乎都无法修复。任何关于我需要在哪里释放内存以避免内存泄漏和seg故障的帮助都将不胜感激 struct list { char *value; struct list *next; struct list *prev; }; const char *list_node_value(list_t *nod

这让我快发疯了。当我在这个双链接列表上运行测试程序时,当我尝试释放列表时,它会给我一个分段错误。我知道由于没有正确释放分配的内存而导致内存泄漏,但无论我做什么尝试,它似乎都无法修复。任何关于我需要在哪里释放内存以避免内存泄漏和seg故障的帮助都将不胜感激

struct list { 

    char *value;
    struct list *next;
    struct list *prev;
};

const char *list_node_value(list_t *node) {

    return node->value;
}

list_t *list_first(list_t *list) {

    return list;
}

list_t *list_last(list_t *list) {

    return list->prev;
}

list_t *list_next(list_t *node) {

    return node->next;
}

list_t *list_previous(list_t *node) {

    return node->prev;

}

static void failed_allocation(void) {

    fprintf(stderr, "Out of memory.\n");
    abort();
}

static list_t *new_node(const char *value) {

    list_t *node = malloc(sizeof(list_t));
    if (!node) failed_allocation();
    node->value = malloc(strlen(value));
    if (!node->value) failed_allocation();
    strcpy(node->value, value);
    return node;
}

list_t *list_insert_before(list_t *list, list_t *node, const char *value) {

    list_t *insert_node = new_node(value);
    insert_node->prev = node->prev;
    insert_node->next = node;
    insert_node->next->prev = insert_node;
    insert_node->prev->next = insert_node;
    if (list == node) {
        return insert_node;
    } else {
        return list;
    }
}

list_t *list_append(list_t *list, const char *value) {

    if (list) {

        (void) list_insert_before(list, list, value);
        return list;
    } else {

        list_t *node = new_node(value);
        node->prev = node->next = node;
        return node;
    }
}

list_t *list_prepend(list_t *list, const char *value) {

    if (list) {

        return list_insert_before(list, list, value);
    } else {

        list_t *node = new_node(value);
        node->prev = node->next = node;
        return node;
    }
}

list_t *list_remove(list_t *list, list_t *node) {

    (node->prev)->next = node->next;
    (node->next)->prev = node->prev;
    if (list != node) {

    return list;
    } else {

        return list->next == list ? NULL : list->next;
    }   
}

void list_free(list_t *list) {

    while (list_remove(list, list_last(list)) != NULL) { }

    }



void list_foreach(list_t *list, void (*function)(const char*)) {

    if (list) {

        list_t *cur = list_first(list);
        do {

            function(cur->value);
            cur = cur->next;
        } while (cur != list_first(list));
    }
}

运行链接到或与的程序


这将告诉您内存丢失或指针取消引用的位置,等等。

您的问题是堆损坏。 你有:

   node->value = malloc(strlen(value));
应该是:

   node->value = malloc(strlen(value)+1);
问题是您没有为
'\0'
NUL字节分配空间。尝试:

if (!node) failed_allocation();
node->value = malloc(strlen(value)+1);

我在这里看到了至少一个缺陷:

node->value = malloc(strlen(value));
保持零终止符字符应为
strlen(value)+1
,否则下一次
strcpy()
调用将导致缓冲区溢出并可能损坏堆:

node->value = malloc(strlen(value) + 1);
  • 你根本没有释放任何东西;从列表中断开连接并不能释放它

  • 它不仅仅是一个双链接列表;这是一份循环清单

  • 我没有看到初始化列表的代码,这可能是问题的根源


  • 你比我快了几秒钟。对不起,我没问这个问题。:)@小毛:对不起,我错过了这个:)为什么在释放列表时会出现问题?如前所述,我可以看到这会导致内存问题,但我如何释放列表?如果我在list_remove函数中放入一个空闲(节点),我只会得到一个segfault@user1691282您将
    free()
    调用放在了什么位置,然后是什么导致seg故障<代码>自由()调用ifself?在释放被删除的节点之前,您应该从中读取数据。@ScottHunter如果缓冲区溢出会损坏该节点,它可能会导致
    free()
    出现问题heap@Rost我把free()放在这样的位置:list\t*list\u remove(list\t*list,list\t*node){(node->prev)->next=node->next;(node->next)->prev=node->prev;如果(list!=node){free(node);return list;}else{return list->next==list?NULL:list->next;}但是我仍然没有释放所有内存,我不知道如何修复它
    node->value = malloc(strlen(value) + 1);