我们说我已定义student struct
:
struct student {
char *name;
};
typedef struct student Student
现在我有以下功能:
void add_student(const char *student_name) {
// create new student
Student *new_s;
new_s = malloc(sizeof(Student));
strncpy(new_s->name, student_name, sizeof(new_s->name) - 1)
}
我想将student_name添加到新学生结构的名称中。但是,由于const char
和char
不同,我必须使用strncpy
。
我试过这种方式,但是我遇到了分段错误,错了什么?
答案 0 :(得分:4)
您只是为此行中的结构new_s
分配内存
new_s = malloc(sizeof(Student));
这包括变量char* name
,即pointer to a char
。虽然,您还需要此指针指向的内存。
因此,您需要为结构内的字符指针name
分配内存。
// create new student
Student *new_s;
new_s = malloc(sizeof(Student));
new_s->name = malloc(100); //assuming you need to store a string of len 100
答案 1 :(得分:2)
正如Johan Wentholt在他的回答中正确概述的那样,你必须为Student
结构和它的成员name
所指向的字符串分配内存,但是你必须返回新结构,这样调用者才能做到与它有关:
Student *add_student(const char *student_name) {
Student *new_s = malloc(sizeof(Student));
if (new_s) {
new_s->name = strdup(student_name);
}
return new_s;
}
您的代码调用未定义的行为,因为您没有为字符串分配内存,更糟糕的是,您将name
成员未初始化(malloc
未初始化它返回的内存)。
此外,您不应使用strncpy
。它是不 strcpy
的某些安全版本,它是一个非常容易出错的函数,大多数程序员都很难理解其语义。 永远不要使用此功能。如果您看到它被使用,您可能会遇到错误,或者有更好的方法来替换它。
为了完整,您的代码:
strncpy(new_s->name, student_name, sizeof(new_s->name) - 1);
尝试将sizeof(char*)-1
中的student_name
个字符最多复制到new_s->name
的数组指针中。
如果student_name
更长,目的地将不会以空终止,
如果它更短,目的地将用空字节填充到给定的大小。
这里目标指针未初始化,大小信息仍然是伪造的:你真的想要复制字符串中的所有字符加上空终止符,这正是strcpy
所做的。但是你需要为此分配足够的内存。你可以使用:
new_s->data = malloc(strlen(student_name) + 1);
strcpy(new_s->data, student_name);
Posix函数strdup()
在一次调用中执行两个操作:
new_s->data = strdup(student_name);
答案 2 :(得分:1)
void add_student(const char *student_name)
{
Student *new_s = malloc(sizeof(Student));
new_s->name = strdup(student_name);
}
请注意,您必须free
new_s->name
而不是free
new_s
。
您还应该检查malloc
和strdup
的返回值是否为NULL
值。如果内存不足,则返回NULL
。
在旁注中,您可以将struct
和typedef
缩短为一个语句,如下所示:
typedef struct student {
char *name;
} Student;