将字符串分配给结构中的指针

时间:2015-07-02 08:09:00

标签: c string struct

#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()已创建指针。)

如果需要动态内存分配,你可以解释一下原因吗?

4 个答案:

答案 0 :(得分:6)

只要您不想修改内容,

person1.forename = "Max";
person1.surname = "Mustermann";

完全有效。

在这种情况下,person1.forename将是指向字符串文字的指针,任何修改内容的尝试都将导致undefined behaviour

那就是说,

  1. 对于print_struct()函数,您不需要传递指向结构的指针。
  2. 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,因为字符串文字具有静态存储持续时间。它们没有动态分配

此函数是一个通用函数,它可以接受各种参数forenamesurname的参数,而不仅仅是字符串文字。

例如,可以像

一样调用该函数
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语句的示例中显示,那么指针将甚至无效。