【问题标题】:Assigning a string to a pointer in a struct将字符串分配给结构中的指针
【发布时间】:2015-07-02 08:09:00
【问题描述】:
#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()

注意:(当然,在这种特定情况下,我还需要更改 change_struct() 中的 realloc() 调用,因为当 realloc() 收到非 malloc()calloc() 时,这是未定义的行为, 或 realloc() 创建的指针。)

如果需要动态内存分配,您能解释一下原因吗?

【问题讨论】:

    标签: c string struct


    【解决方案1】:

    只要不想修改内容,

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

    完全有效。

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

    也就是说,

    1. 对于print_struct() 函数,您不需要传递指向结构的指针。
    2. sizeof(char) 保证在C 中产生1。使用它进行乘法(得到malloc() 中的大小)是多余的,可以很容易地省略。

    【讨论】:

    • 我不知道,但我的印象是,C 现在在反对和赞成票方面是一个相当苛刻的标签。 (不是试图开始讨论。)
    【解决方案2】:
    person1.forename = "Max";
    person1.surname = "Mustermann";
    

    您正在使指针指向字符串文字,因此请注意字符串文字是只读的。因此,一旦进行了上述初始化,就无法修改指针指向的字符串,malloc() 和系列函数分配的内存并非如此。

    由于您正在显式分配内存,因此您可以使用它来读取和写入。因此,如果您希望修改指针指向的字符串,则需要在此处进行动态内存分配

    【讨论】:

      【解决方案3】:

      "Max" 是 C 中以 null 结尾的只读字符串文字;使用const char* 指向第一个字符是明确且惯用的。

      如果您要以修改只读文字的行为未定义这样的方式填充它,则应该将结构元素的类型更改为const char*。。 p>

      当然,你可以设置forename &c。指向另一个字符串。

      【讨论】:

        【解决方案4】:

        这是一个糟糕的方法。在这种情况下,您可能不会在函数 change_struct 内应用函数 realloc,因为字符串文字具有静态存储持续时间。它们不是动态分配的

        这个函数是一个通用函数,它可以接受参数 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 语句所示,则指针甚至无效。

        【讨论】:

          猜你喜欢
          • 2021-04-29
          • 1970-01-01
          • 2013-12-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-06
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多