即使我正在使用 malloc,strcpy 上的分段错误

Segmentation fault on strcpy even though I am using malloc

我正在尝试用 C 语言制作一个双向链表。

即使我使用 malloc,我也会遇到分段错误。

到目前为止,这是我的代码。

list.h

#ifndef _LIST_
#define _LIST_

typedef struct listnode
{
    char * data;
    struct listnode * next;
    struct listnode * prev;
}listnode;

typedef struct list
{
    listnode * firstnode; // it will point to the first element in the list
    int size; // the size of the list
}list;

list create_list();
void insert_first_element(char *, list);

#endif

list.c

#include "list.h"
#include <stdlib.h>
#include <string.h>

list create_list()
{
    list L;
    L.firstnode= NULL;
    L.size = 0;

    return L;
}

void incert_first_element(char * d, list L)
{
    listnode * N= (listnode *)malloc(sizeof(listnode));
    
    strcpy(N->data, d); // <-- I get Segmentation Fault Here

    if(L.firstnode != NULL)
    {
        N->next=L.firstnode;
        N->prev=L.firstnode->prev;
        L.firstnode->prev=N;
        L.firstnode=N;
    }
    else
    {
        N->next=NULL;
        N->prev=N;
        L.firstnode=N;
    }
    L.size++;
    return 0;
}

main.c

#include <stdio.h>
#include "list.h"

int main(void)
{
   list L = create_list();
   incert_first_element("test",L);
  
   return 0;
}

知道是什么导致了分段错误吗?

因为我在谷歌搜索时发现的任何问题都是由于缺少malloc造成的,但我在这里实现了。

此代码

listnode * N= (listnode *)malloc(sizeof(listnode));

strcpy(N->data, d); // <-- I get Segmentation Fault Here

分配了一个 listnode 结构,但是 data 字段是 char 上的一个 指针 ,所以它没有被 malloc打电话。

第二行应该替换为 strdup 调用

N->data = strdup(d);

解除分配也应该分两次完成。首先 free(N->data) 然后 free(N)

您的代码中存在多个问题:

  • incert_first_element 收到 list 结构的副本并对其进行修改。这对调用者的 list object 没有影响。您应该将指针传递给调用者的 list object.

  • incert_first_element 函数分配一个新的 listnode object,但不是为字符串。成员 data 是一个指针,而不是一个数组,malloc() 没有初始化它所以 strcpy(N->data, d); 将字符复制到一个未初始化的指针中,调用未定义的行为(一个分段错误使程序停止)。您应该使用 N-strcpy(N->data, d);

    分配字符串的副本
  • 你在双向链表的开头插入节点,因此设置N->prev = N;是不正确的,前一个节点应该设置为NULL这两种情况。

  • list.c,你应该#include "list.h"标准headers.

这是修改后的版本:

list.h

#ifndef LIST_H
#define LIST_H

typedef struct listnode {
    char *data;
    struct listnode *next;
    struct listnode *prev;
} listnode;

typedef struct list {
    listnode *firstnode; // it will point to the first element in the list
    int size; // the size of the list
} list;

list create_list(void);
void insert_first_element(list *, const char *);
#endif

list.c

#include <stdlib.h>
#include <string.h>
#include "list.h"

list create_list(void) {
    list L = { NULL, 0 };
    return L;
}

void insert_first_element(list *L, const char *d) {
    listnode *N = malloc(sizeof(*N));
    if (N == NULL) {
        return -1;
    }
    N->data = strdup(d);
    N->prev = NULL;
    N->next = L->firstnode;

    if (L->firstnode != NULL) {
        L->firstnode->prev = N;
    }
    L->firstnode = N;
    L->size++;
    return 0;
}

main.c

#include <stdio.h>
#include "list.h"

int main(void) {
   list L = create_list();
   insert_first_element(&L, "test");
  
   return 0;
}