【问题标题】:Segmentation Fault (singal 11 sigsegv) with linked list带链表的分段错误(信号 11 sigsegv)
【发布时间】:2016-11-29 05:11:21
【问题描述】:

在 pset5 之前使用链表和指针编写一个程序来练习,结果留下了两个我无法纠正的内存错误。

#include <stdio.h>
#include <stdlib.h>

//define struct for Nodes
typedef struct list
{
    int data;
    int key;
    struct list* next;
}Node;

//function declarations
Node* create(int a, int *counter);
void insert(int a, int *counter);
void delete_list();
void printlist();


//global pointers
Node* Head = NULL;
Node* Current = NULL;


int main()
{
    int *keycounter =(int*)malloc(sizeof(int));
    int value = 20;
    keycounter = 0;
    Head=create(value, keycounter);
    value = 30;
    insert(value, keycounter);
    value = 40;
    insert(value, keycounter);
    printlist();
    delete_list();

    free(keycounter);
    return 0;
}
// VV functions VV
void delete_list()
{
    free(Head);
    free(Current);
}

Node* create(int a, int *counter)
{
    Node* ptr=malloc(sizeof(Node));
    if(!ptr)
    {
        printf("ERROR-NOT ENOUGH MEMORY\n");
        free(ptr);
        return 0;
    }
        ptr->data=a;
        ptr->key=*counter;
        counter++;

        return ptr; 

}

void insert(int a, int *counter)
{
    Node* ptr=malloc(sizeof(Node));
    if(!ptr) {
        printf("ERROR-NOT ENOUGH MEMORY\n");
        free(ptr);
    }
    ptr->data=a;
    ptr->key=*counter;

    //point next field to old head
    ptr->next=Head;

    //assign current node as head of singly linked list
    Head=ptr;
    counter++;
}

//Thank you guys over at tutorialspoint for this neat idea for testing this.
//https://www.tutorialspoint.com/data_structures_algorithms/linked_list_program_in_c.htm
void printlist()
{
    Node* ptr=Head;
    printf("TESTING\n");
    while(ptr != NULL) {
        printf("%p*NODE* KEY:%i VALUE:%i PTR NEXT:%p\n \n", ptr, ptr->key, ptr->data, ptr->next);
        ptr=ptr->next;
    }
}

这是我的 valgrind 输出:

仍然学习这么多 valgrind 输出对我来说非常神秘,堆栈交换中有关“信号 11 (SIGSEGV)”错误的线程也很难理解。

另外,任何关于我的代码的提示或建议都将不胜感激。

【问题讨论】:

  • 您必须正确处理next 成员。在创建节点时始终将其初始化为 NULL,并在将节点添加到列表时进行适当的更改。
  • 一个好的开始是附加一个调试器,例如gdb,然后查看堆栈跟踪以了解程序崩溃的位置。
  • 在此处发布您的代码,而不是发布链接。
  • 问题是:在 malloc 之后,您的指针“keycounter”指向有效地址,但在下一行您传递 keycounter=0,即指向 NULL。我觉得这是一个错字,你想用 0 初始化 keycounter,所以你应该写 *keycounter = 0 而不是 keycounter = 0。
  • 不要将代码放在外部网站上,don't put images of code and text output 除非确实有必要。在这里复制粘贴即可

标签: c linked-list segmentation-fault cs50


【解决方案1】:

您的代码有问题。请参阅以下几行:

int main()
{
    int *keycounter =(int*)malloc(sizeof(int));
    int value = 20;
    keycounter = 0; ===> You are setting the pointer to NULL effectively nullifying the effect of your malloc call above

因此,在您的创建函数中,当您尝试访问计数器时,会导致 NULL 指针取消引用

Node* create(int a, int *counter)
{
    Node* ptr=malloc(sizeof(Node));
    if(!ptr)
    {
        printf("ERROR-NOT ENOUGH MEMORY\n");
        free(ptr);
        return 0;
    }
        ptr->data=a;
        ptr->key=*counter; ==> Here it will lead to NULL pointer dereference

如果你在struct中的key成员只是一个整数,那么不需要传递指针(计数器是指针),你也可以传递一个整数并设置它。

【讨论】:

  • 比这更糟糕。设置指向地址0 的指针正好在系统保留内存范围 内,尝试访问或写入它会保证出现段错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-10
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多