使用链表获取段错误

时间:2018-01-24 07:35:13

标签: c linked-list

对这个非常基本的问题抱歉,但我无法解决这个问题。我正在尝试构建一个简单的链表,并在C中附加一些值。

下面是list.c文件

#ifndef List_h
#define List_h

#include <stdlib.h>

typedef struct node {
    int value;
    struct node *next;
} Node;

typedef struct {
    Node *head;
    Node *tail;
    int size;
} List;

List *createList();
void appendList(List *, int num);
Node *removeList(List *);
void printList(List *);

#endif

以下是头文件

while

在运行调试器的过程中,我的代码似乎运行正常,这样做的意义就更小了。

我认为我的问题出现在appendList内的current->next != NULL循环中,我试图访问一些未分配的内存。问题是我正在制作的问题NULL吗?访问未分配的内存是否必须返回updated:{ key: 'updated', label: 'Updated', formatter: (value, key, item) => { return moment(item.updated).format('DD-MM-YYYY'); } }

3 个答案:

答案 0 :(得分:2)

嗯,我的想法是你已经创建了最初的头部和尾部Node,而你没有设置它的值。稍后您使用value来确定是否需要添加另一个节点或将头和尾设置为传递的值:

void appendList(List *list, int num) {
    if(list->head->value == 0) {
        list->head->value = num;
        list->tail->value = num;
        return;
    }
    ...

malloc返回的内存必须为零,因此您的算法应确保在继续之前设置所有值。

然后,您将继续到达列表的末尾:

Node *current = calloc(1, sizeof(Node));
current = list->head;
while(current->next != NULL) {
    current = current->next;
}

但是,再次,list->head存在时,您永远不会设置list->head->next的值!在最好的情况下,一个未分配的指针不会很好地结束。

考虑创建一个创建新节点的方法:

Node* createNode() {
    Node* node = malloc(sizeof(Node));
    if(node == NULL) {
        return NULL;
    }
    node->value = 0;
    node->next = NULL;
    return node;
}

另请注意,这里的代码有一个小的修正(与您的分段错误无关,但仍可能造成内存泄漏):

list->head = malloc(sizeof(Node));
list->tail = malloc(sizeof(Node));
if(list->head == NULL || list->tail == NULL) {
    free(list);
    return NULL;
}

请注意 可以list->head正确分配内存,而list->tail 可以正确分配内存。在这种情况下,您可能会因list->head而导致内存泄漏。请采取必要的预防措施。

答案 1 :(得分:1)

特别是在嵌入式系统中,为调试模式编译的代码和用于发布模式的代码可能不同。因此,对我来说,您的代码在调试中工作并且在发布中不会出现并不奇怪。

使用malloc创建链接列表时,编译器可能会设置&#34; struct node * next&#34;的地址。元素,内存中不可访问的位置。因此,如果您尝试访问它,您将获得段错误。 (或MacOS中的BAD_EXC)

如果您怀疑malloc是您的问题,请尝试创建一个没有malloc的小列表,看看您是否有段错误,即使用:

struct node myNode;
struct node* pmyNode = &myNode;

在您的while循环中,我想,您正试图转到列表的最后一个元素。所以,而不是:

while(current->next != NULL) {
    current = current->next;
}

尝试这样做:

last_linked_list_element->next = last_linked_list_element;

current = first_linked_list_element;

while(current != current->next) {
    current = current->next;
}

当您在列表的最后一个元素时,您将跳出循环。

另一种解决方案是尝试:

last_linked_list_element->next = NULL;

last_linked_list_element->next = &random_identifier;

这将确保指针位于内存中的可访问位置。这会解决您的问题吗?

答案 2 :(得分:0)

除了上一篇文章之外,还有以下代码:

Node *current = calloc(1, sizeof(Node));
current = list->head;
while(current->next != NULL) {
    current = current->next;
}

你应该删除行Node *current = calloc(1, sizeof(Node));,因为这样你分配内存而不是使用它(随后你将currect指针分配给另一个值。)