将字符串指定给结构-链表C中的指针

将字符串指定给结构-链表C中的指针,c,linked-list,c-strings,C,Linked List,C Strings,我正试图用C语言为学生写一个链表程序。 以下是结构: typedef struct student *studp; typedef struct student{ int number; char *name; char *date; unsigned grade; studp next; }stud; 现在我想写一个函数,它创建新节点并为成员赋值。 我不知道怎么做,下面是函数: studp create_stud(int number, char *n

我正试图用C语言为学生写一个链表程序。 以下是结构:

typedef struct student *studp;
typedef struct student{
    int number;
    char *name;
    char *date;
    unsigned grade;
    studp next;
}stud;
现在我想写一个函数,它创建新节点并为成员赋值。 我不知道怎么做,下面是函数:

studp create_stud(int number, char *name, char *date, unsigned grade){
studp item = (studp)malloc(sizeof(stud));
if(!item){
    printf("Cannot allocate memory\n");
    exit(1);
}
item->number = number;
item->name = .....


return item;
} 我应该如何将文本分配给成员名称和日期?我可以使用运算符“=”:

item->name = name;
或者我应该用malloc()分配内存? 如果我使用malloc(),我应该释放程序and中的指针还是释放节点? 谢谢

这样就行了。如果您没有这个(
strdup
是POSIX的东西),请分配内存,然后使用
strcpy
/
memcpy
复制
name
指向的字符串

不要将指针隐藏在
typedef
中,在大型代码库中更容易维护-您必须始终回过头来了解编写正确代码的类型

不要强制转换
malloc
的返回值,并检查
strdup
的返回值,就像您对
malloc
所做的那样。另外,
free
使用
malloc
strdup
分配的内存

给你举个例子。(插图)


编辑:如果
strdup
不存在

item->name = malloc(strlen(name)+1);
if(!item->name){
   perror("malloc");
   exit(EXIT_FAILURE);
}
memcpy(item->name, name, strlen(name)+1);
这样就行了。如果您没有这个(
strdup
是POSIX的东西),请分配内存,然后使用
strcpy
/
memcpy
复制
name
指向的字符串

不要将指针隐藏在
typedef
中,在大型代码库中更容易维护-您必须始终回过头来了解编写正确代码的类型

不要强制转换
malloc
的返回值,并检查
strdup
的返回值,就像您对
malloc
所做的那样。另外,
free
使用
malloc
strdup
分配的内存

给你举个例子。(插图)


编辑:如果
strdup
不存在

item->name = malloc(strlen(name)+1);
if(!item->name){
   perror("malloc");
   exit(EXIT_FAILURE);
}
memcpy(item->name, name, strlen(name)+1);

您的结构包含
char*
成员。它们可以指向字符串,但不能包含字符串。为了复制这些字符串成员,需要为新结构中的
char*
字段分配缓冲区,然后对内容分配
strncpy()


释放您分配的所有内存是您的责任。想象一下,好像每个
malloc
调用都需要一个匹配的
免费
。我建议编写相应的
delete\u stud
函数来处理清理。它可以释放与结构相关联的内存,以及为
char*
成员分配的任何缓冲区。

您的结构包含
char*
成员。它们可以指向字符串,但不能包含字符串。为了复制这些字符串成员,需要为新结构中的
char*
字段分配缓冲区,然后对内容分配
strncpy()



释放您分配的所有内存是您的责任。想象一下,好像每个
malloc
调用都需要一个匹配的
免费
。我建议编写相应的
delete\u stud
函数来处理清理。它可以释放与结构相关的内存,以及为
char*
成员分配的任何缓冲区。

在typedef下隐藏指针是邪恶的。你是什么意思>,调用
studp
,看起来很像
strdup()
会让我发疯的。@ToharPingley说你永远不应该做
typedef POINTER\u TYPE*NON\u POINTER\u TYPE
,因为它让人困惑。@IharobAlAsimi明白了。在typedef下隐藏指针是邪恶的。你是什么意思>,调用
studp
看起来像
strdup()
会让我发疯的。@ToharPingley说你永远不应该做
typedef POINTER\u TYPE*NON\u POINTER\u TYPE
,因为它很混乱。@IharobAlAsimi明白了。@ToharPingley是的,你应该这样做,就像
malloc()
strdup()
失败时会返回
NULL
。您还应该
free()
指针,
strdup()
返回的指针是
malloc()
内部返回的指针,因此所有相同的规则都适用。如果你的意思是你害怕传递一个
NULL
指针,那么是的,检查一下,传递
NULL
strdup()
@ToharPingley()是不可能的。这取决于-如果你需要在这里验证输入,那么你必须,但是如果你用已经验证过的输入调用这个函数,那么你就不必了。谢谢!如果我写了一个函数来释放列表,我应该加上:“free(name)”?@ToharPingley是的,注意它将是
free(studp\u instance->name)
,但是是的,这就是注释试图说的。答案现在也包括它。如果我使用strcpy(),这不是一个安全问题吗?@ToharPingley是的,你应该这样做,就像
malloc()
strdup()
在失败时返回
NULL
。您还应该
free()
指针,
strdup()
返回的指针是
malloc()
内部返回的指针,因此所有相同的规则都适用。如果你的意思是你害怕传递一个
NULL
指针,那么是的,检查一下,传递
NULL
strdup()
@ToharPingley()是不可能的。这取决于-如果你需要在这里验证输入,那么你必须,但是如果你用已经验证过的输入调用这个函数,那么你就不必了。谢谢!如果我写了一个函数来释放列表,我应该加上:“free(name)”?@ToharPingley是的,注意它将是
free(studp\u instance->name)
,但是是的,这就是注释试图说的。答案现在也包括它。如果我使用strcpy(),这不是一个安全问题吗?
item->name = malloc(strlen(name)+1);
if(!item->name){
   perror("malloc");
   exit(EXIT_FAILURE);
}
memcpy(item->name, name, strlen(name)+1);