#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *forename;
char *surname;
int age;
};
void change_struct(struct Person *person, char *forename, char *surname,
int age);
void print_struct(struct Person *person);
int main(void)
{
struct Person person1;
person1.forename = malloc((strlen("Max") + 1) * sizeof(char));
if (!person1.forename) {
exit(EXIT_FAILURE);
}
strcpy(person1.forename, "Max");
person1.surname = malloc((strlen("Mustermann") + 1) * sizeof(char));
if (!person1.surname) {
exit(EXIT_FAILURE);
}
strcpy(person1.surname, "Mustermann");
person1.age = 35;
print_struct(&person1);
change_struct(&person1, "Hans", "Bauer", 45);
print_struct(&person1);
free(person1.forename);
free(person1.surname);
exit(EXIT_SUCCESS);
}
void change_struct(struct Person *person, char *forename, char *surname,
int age)
{
person->forename = realloc(person->forename,
(strlen(forename) + 1) * sizeof(char));
if (!person->forename) {
exit(EXIT_FAILURE);
}
strcpy(person->forename, forename);
person->surname = realloc(person->surname,
(strlen(surname) + 1) * sizeof(char));
if (!person->surname) {
exit(EXIT_FAILURE);
}
strcpy(person->surname, surname);
person->age = age;
}
void print_struct(struct Person *person)
{
printf("%s\n", person->forename);
printf("%s\n", person->surname);
printf("%d\n", person->age);
}
将字符串分配给struct
中的指针时,如果我愿意的话,它是明确定义的行为
person1.forename = "Max";
person1.surname = "Mustermann";
最初在main()
中而不是使用malloc()
和strcpy()
?
注意:(当然在这种特定情况下,我还需要更改realloc()
中的change_struct()
次调用,因为当realloc()
收到非{malloc()
时,它是未定义的行为{1}},calloc()
或realloc()
已创建指针。)
如果需要动态内存分配,你可以解释一下原因吗?
答案 0 :(得分:6)
只要您不想修改内容,
person1.forename = "Max";
person1.surname = "Mustermann";
完全有效。
在这种情况下,person1.forename
将是指向字符串文字的指针,任何修改内容的尝试都将导致undefined behaviour。
那就是说,
print_struct()
函数,您不需要传递指向结构的指针。sizeof(char)
保证在1
中生成C
。使用它进行乘法(得到malloc()
中的大小)是多余的,可以很容易地省略。答案 1 :(得分:1)
person1.forename = "Max";
person1.surname = "Mustermann";
您正在指向字符串文字,因此请注意字符串升序是只读的。因此,一旦进行了上述初始化,就无法修改指针所指向的字符串,这与malloc()
和族函数分配的内存不同。
由于你明确地分配内存,你可以用它来读写。所以如果你想修改指针所指向的字符串,你需要动态内存分配
答案 2 :(得分:1)
"Max"
是C中以null结尾的只读字符串文字;使用const char*
指向第一个字符是明确定义和惯用的。
如果要以修改只读文字的行为 undefined 的方式填充结构元素的类型,则应将结构元素的类型更改为const char*
。
当然,您可以设置forename
&amp; c。指向另一个字符串。
答案 3 :(得分:0)
这是一个糟糕的方法。在这种情况下,您可能无法在函数realloc
中应用函数change_struct
,因为字符串文字具有静态存储持续时间。它们没有动态分配
此函数是一个通用函数,它可以接受各种参数forename
和surname
的参数,而不仅仅是字符串文字。
例如,可以像
一样调用该函数char name[] = "Hans";
change_struct(&person1, name, "Bauer", 45);
甚至喜欢
if ( some_condition )
{
char name[] = "Hans";
change_struct(&person1, name, "Bauer", 45);
}
在这种情况下,name
的任何更改也将更改结构类型对象的数据成员forename
指向的字符串。此外,如果数组name
将在某个局部作用域中定义,因为它在if语句的示例中显示,那么指针将甚至无效。