1
#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);
}

When assigning a string to a pointer in a struct is it well-defined behaviour if I would do

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

in main() initially instead of using malloc() and strcpy()?

NOTE: (Of course in this specific case I would need to also change the realloc() calls in change_struct() since it is undefined behaviour when realloc() receives a non- malloc(), calloc(), or realloc() created pointer.)

If dynamic memory allocation should be required could you give an explanation why?

4 Answers 4

6

As long as you don't want to modify the contents,

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

are perfectly valid.

In this case, person1.forename will be a pointer to the string literal and any attempt to modify the contents will result in undefined behaviour.

That said,

  1. for print_struct() function, you don't need to pass a pointer to the structure.
  2. sizeof(char) is guaranteed to produce 1 in C. Using it for multiplication (to get the size in malloc())is redundant, can be omitted easily.
Sign up to request clarification or add additional context in comments.

1 Comment

I don't know but I am under the impression that C is quite a harsh tag by now in terms of down- and upvotes. (Not trying to start a discussion.)
1
person1.forename = "Max";
person1.surname = "Mustermann";

You are making your pointers point to string literals , so make a note that string literls are read-only. So once you have the above initialization you can't modify the string the pointer is pointing to which is not the case with the memory allocated by malloc() and family functions.

Since you are allocating memory explicitly you can use it to read and write.So you need dynamic memory allocation here if you wish to modify the string the pointers are pointing to

Comments

1

"Max" is a null-terminated read-only string literal in C; using a const char* to point to the first character is well-defined and idiomatic.

You ought to change the types of your structure elements to const char* if you are going to populate it in such a manner as the behaviour on amending a read-only literal is undefined.

Of course, you can set forename &c. to point to another character string.

Comments

0

It is a bad approach. In this case you may not apply function realloc inside function change_struct because string literals have static storage duration. They are not allocated dynamically

This function is a general-purpose function and it can accept arguments for parameters forename and surname of various kind not only string literals.

For example the function can be called like

char name[] = "Hans";

change_struct(&person1, name, "Bauer", 45);

Or even like

if ( some_condition )
{
    char name[] = "Hans";

    change_struct(&person1, name, "Bauer", 45);
}

In this case any changing of name will also change the string pointed to by data member forename of an object of the type of the structure. Moreover if array name will be defined in some local scope as it is shown in the example with the if statement then the pointer will be even invalid.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.