即使我正在使用 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;
}
我正在尝试用 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;
}