在结构上使用 strncpy
Posted
技术标签:
【中文标题】在结构上使用 strncpy【英文标题】:Using strncpy on struct 【发布时间】:2016-05-25 11:56:48 【问题描述】:假设我定义了这个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
。
我尝试过这种方式,但是出现分段错误,怎么了?
【问题讨论】:
你可能想看看strdup
,而不是strncpy
。这听起来与您尝试在此处存档的内容非常接近。
永远不要使用strncpy
它永远不是适合这项工作的工具。
【参考方案1】:
正如 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
较长,则目的地不会以null结尾,
如果它更短,目标将用空字节填充,直到给定大小。
这里的目标指针是未初始化的,而且大小信息是假的:你真的想复制字符串中的所有字符加上空终止符,这正是strcpy
所做的。但是您需要为此分配足够的内存。你可以使用:
new_s->data = malloc(strlen(student_name) + 1);
strcpy(new_s->data, student_name);
Posix 函数 strdup()
在一次调用中完成这两项操作:
new_s->data = strdup(student_name);
【讨论】:
这是真的,但我使用的是 baketurtle 提供的示例。【参考方案2】:Haris 给出了一个很好的解决方案。但就像 Florian Zwoch 在 cmets 中所说,您也可以像这样使用 strdup:
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;
【讨论】:
【参考方案3】:你只是在这一行中为结构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
【讨论】:
所以在分配 new_s->name 之后,我可以这样使用 strncpy 吗? strncpy(new_group->name, group_name, ) @bakedturtle,唯一的问题是您没有分配内存。否则,添加该行后,您的代码应该可以工作。你为什么不跑过去检查一下。 嗯 - 对我来说看起来像 1 倍。 "...100);
--> //假设你需要存储一个长度为 100 的字符串"。字符串长度一般不包含空字符,建议“存储长度不超过99的字符串”。以上是关于在结构上使用 strncpy的主要内容,如果未能解决你的问题,请参考以下文章