【问题标题】:C segmentation fault when trying to implement LinkedList尝试实现 LinkedList 时出现 C 分段错误
【发布时间】:2013-04-06 12:39:06
【问题描述】:

我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXN 100
typedef int key;
typedef int data;
struct list * createElement(key k, data info);

struct list{
    key k;
    data info;
    struct list *next;
};
struct list *L;
void init(key k, data info)
{
    L = createElement(k, info);
}
struct list * createElement(key k, data info)
{
    struct list *temp;
    temp = (struct list *) malloc(sizeof(*temp));
    temp->k = k;
    temp->info = info;
    return temp;
}
void insert(struct list * element)
{
    element->next = L;
    L = element;
}
void insertBefore(struct list * element, key k)
{
    struct list * currentElement = L;
    while(currentElement != NULL)
    {
        if(currentElement->k == k)
        {
            struct list *temp = currentElement;
            currentElement = element;
            currentElement->next = temp;
            return;
        }
        currentElement = currentElement->next;
    }

}
void insertAfter(struct list * element, key k)
{
    struct list * currentElement = L;
    while(currentElement != NULL)
    {
        if(currentElement->k == k)
        {
            struct list *temp = currentElement->next;
            currentElement->next = element;
            element->next = temp;
            return;
        }
        currentElement = currentElement->next;
    }
}
void deleteElement(struct list * element)
{
    struct list * currentElement = L;
    while(currentElement != NULL)
    {
        if(currentElement == element)
        {
            struct list * temp = currentElement;
            currentElement = currentElement->next;
            free(temp);
            return;
        }
        currentElement = currentElement->next;
    }
}
struct list * getElementByKey(key k) {
    printf("\n1");
    struct list *currentElement = L;
    printf("2");
    while(currentElement != NULL)
    {
        printf("3");
        if(currentElement->k == k)
        {
            printf("4");
            return currentElement;
        }
        printf("5");
        currentElement = currentElement->next;
        printf("6");
    }
    printf("There is no such element in the list");
}
struct list * pop()
{
    struct list *element = L;
    L = L->next;
    return element;
}
int main()
{
    init(0, 13);
    struct list * element = createElement(5, 155);
    insert(element);
    struct list * k = createElement(7, 243);
    insert(k);
    //insertBefore(createElement(3, 100), 5);
    printf("The first element value is: %d", pop()->info);
    printf("The second element value is: %d", pop()->info);
    printf("The  element value is: %d", getElementByKey(5)->info);

    return 0;
}

所以当我执行它时,调试器在第 84 行给我分段错误,即方法 getElementByKey 上的 if(currentElement-&gt;k == k)。我知道我正在尝试访问一个不存在的元素(因为我使用 pop 方法并且它删除了列表中的第一个元素)但它应该给我打印一条警告消息。似乎前一个元素的键有问题或者我没有注意到的东西。

【问题讨论】:

  • 标题错字不错,顺便说一句... ;-)
  • 是的,谢谢刚刚注意到

标签: c pointers segmentation-fault


【解决方案1】:

在您的 createElement 函数中,您忘记将 next 指针初始化为 NULL。

struct list * createElement(key k, data info)
{
    struct list *temp;
    temp = (struct list *) malloc(sizeof(*temp));
    temp->k = k;
    temp->info = info;
    temp->next = NULL;
    return temp;
}

因此,当您浏览列表时,它永远不会找到列表的最后一个元素,因为下一个指针永远不会等于 NULL,并且会进入内存中的某个随机位置,试图访问不允许这样做的部分.

【讨论】:

  • 谢谢!这解决了我的问题。我认为编译器会自动将它分配给 NULL,因此不需要编写它(我有一个 PHP 背景,这就是那里的工作方式)。这确实给了我一个教训。
  • 是的,一定要在 C 中初始化所有东西,调试一个未初始化的变量会浪费很多时间。
【解决方案2】:

当删除一个元素时(使用deleteElement()),你错过了重新初始化L。


if(currentElement-&gt;k == k)most likey 中的段违规是由于currentElement 引用了无效的内存地址。当您测试第 84 行之前的某些行是否针对 NULL 时,只能是 currentElement 被明确分配了一个无效地址,或者它指向的地址已经被释放。

从deleteElement() 中显示的代码我假设是后者。

【讨论】:

  • “当删除一个元素时(使用 deleteElement())你错过了重新初始化 L.”是什么意思?我对C和指针没有太多经验。我没有使用 deleteElement 方法,所以它不喜欢这个特定的错误。我将尝试查看 currentElement 链接到坏内存的位置
  • deleteElement() 不正确,您需要在使用前修复它。假设您删除了 L 指向的元素。整个列表都消失了,因为 L 指向的内存已经被 free() 了。
【解决方案3】:

两个问题

1)在 createElement() 处

需要

temp-&gt;next = NULL;

2)在 insertBefore()

不改变列表的指针

currentElement = element;

例如)

void insertBefore(struct list * element, key k)
{
    struct list * currentElement = L; //add case of L->k
    while(currentElement != NULL)
    {
        if(currentElement->next && currentElement->next->k == k)
        {
            element->next = currentElement->next;
            currentElement->next = element;
            return;
        }
        currentElement = currentElement->next;
    }
}

【讨论】:

  • getElementByKey():未找到时返回值未确定。
  • 这是实现它的好方法,但我的方法是相同的,应该可以正常工作。
  • @user1113314,你觉得currentElement = element;谁在指向element?
猜你喜欢
  • 2017-02-14
  • 2014-09-05
  • 2022-10-19
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2012-07-01
相关资源
最近更新 更多